LWJGL Forum

Programming => OpenGL => Topic started by: bogieman987 on December 17, 2014, 09:07:43

Title: Framebuffer Black Screen
Post by: bogieman987 on December 17, 2014, 09:07:43
Hey guys,

Anyone know what may cause the framebuffer to produce a black texture.
glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) returns 36053 or "GL_FRAMEBUFFER_COMPLETE".

The stuff to be rendered, are rendered when not using the framebuffer.
The rectangle I'm using to render the framebuffer texture to appears to render fine.

Here's the code for rendering and the framebuffer
Framebuffer
public void init() {
try {
System.out.println("---Creating Framebuffer---");

getRect().init();
getRect().spawn();

setFbo(GL30.glGenFramebuffers());
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, getFbo());

// Texture for color
setTexture(GL11.glGenTextures());
GL11.glBindTexture(GL11.GL_TEXTURE_2D, getTexture());
GL42.glTexStorage2D(GL11.GL_TEXTURE_2D, 1, GL30.GL_RGBA16F, getWidth(), getHeight());

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);

// Texture for depth
setDepth(GL11.glGenTextures());
GL11.glBindTexture(GL11.GL_TEXTURE_2D, getDepth());
GL42.glTexStorage2D(GL11.GL_TEXTURE_2D, 1 , GL30.GL_DEPTH_COMPONENT32F, getWidth(), getHeight());

GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
GL11.GL_TEXTURE_2D, getTexture(), 0);
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
GL11.GL_TEXTURE_2D, getDepth(), 0);

GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);

// The buffers given would contain things like GL30.GL_COLOR_ATTACHMENT0 inside an int array where here
// it's converted a buffer
IntBuffer drawBuffers = BufferUtils.createIntBuffer(getColorAttachment().length);
for(int i = 0; i < getColorAttachment().length; i++) {
drawBuffers.put(getColorAttachment()[i]);
}
drawBuffers.flip();

GL20.glDrawBuffers(drawBuffers);

GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

errorCheck();

System.out.println("---Created Framebuffer---");
} catch (GLErrorException e) {
e.printStackTrace();

System.exit(1);
}
}

Render code
@Override
protected void render() {
try {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

//GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, getFrameBuffer().getFbo());

GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
GL11.glLineWidth(2.0f);


GL20.glUseProgram(getShaderProgs()[0].getShaderProg());

// Projection Matrix
getMatrixBuffer().setData(getCamera().getProjectionMatrix());
GL20.glUniformMatrix4(getShaderProgs()[0].getUniform(uniNames[0]).getLocation(), false,
getMatrixBuffer().getBuffer());

// View Matrix
getMatrixBuffer().setData(getCamera().getViewMatrix());
GL20.glUniformMatrix4(getShaderProgs()[0].getUniform(uniNames[1]).getLocation(), false,
getMatrixBuffer().getBuffer());

if(GameObjectPool.getAssetPool() != null) {
for( BaseGameObject elem : GameObjectPool.getAssetPool()) {
// TODO Set up if expected model isn't loaded, game will load error model.
// getMatrixBuffer().setMassData(elem.getMeshMatrix().toArray(new Matrix4f[elem.getMeshMatrix().size()]));

GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, elem.getMesh().getIVbo());
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getMatrixBuffer().getBuffer(), GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

//TODO seperate texture, so if it fails, render error texture
                                //Commented out so I just render a single texture
// for(int i = 0; i < elem.getMaterial().getTextures().length; i++) {
// GL20.glUniform1i(getShaderProgs()[0].getUniform(uniNames[i + 2]).getLocation(), i);
// GL13.glActiveTexture(GL13.GL_TEXTURE0 + i);
// GL11.glBindTexture(GL11.GL_TEXTURE_2D, elem.getMaterial().getTextures()[i].getVboT());
// }

// Render single texture
GL20.glUniform1i(getShaderProgs()[0].getUniform(uniNames[2]).getLocation(), 0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, elem.getMaterial().getTextures()[0].getVboT());

GL30.glBindVertexArray(elem.getMesh().getVao());

GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, elem.getMesh().getVboI());

getRenderMethods().DrawElementsInstanced(elem.getMesh().getVboI(), elem.getMesh().getIndiceCount(),
elem.getMeshMatrix().size());

}
}

errorCheck();
} catch (GLErrorException e) {
e.printStackTrace();
}
}

@Override
protected void postProc() {
try {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);

clear();

GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);

GL20.glUseProgram(getShaderProgs()[1].getShaderProg());

// Bind object data
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, getFrameBuffer().getRect().getIVbo());
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, getMatrixBuffer().getBuffer(), GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);

// Bind texture data
GL20.glUniform1i(getShaderProgs()[1].getUniform(fbUniNames[0]).getLocation(), 0);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, getFrameBuffer().getTexture());

GL30.glBindVertexArray(getFrameBuffer().getRect().getVao());

GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, getFrameBuffer().getRect().getVboI());

getRenderMethods().DrawElementsInstanced(getFrameBuffer().getRect().getVboI(),
getFrameBuffer().getRect().getIndiceCount(), getFrameBuffer().getRect().getMatrix().size());

errorCheck();
} catch (GLErrorException e) {
e.printStackTrace();
}
}
Title: Re: Framebuffer Black Screen
Post by: quew8 on December 17, 2014, 10:36:22
I would recommend comparing your code to this example from the old LWJGL2 wiki http://wiki.lwjgl.org/wiki/Render_to_Texture_with_Frame_Buffer_Objects_(FBO) (http://wiki.lwjgl.org/wiki/Render_to_Texture_with_Frame_Buffer_Objects_(FBO)).
Title: Re: Framebuffer Black Screen
Post by: bogieman987 on December 17, 2014, 12:34:34
Well I got it sorted, first I uncommented line 6 in the render code which had GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, getFrameBuffer().getFbo());
And then I added the clear(); method.

In case anyone was wondering here's the code inside the clear(); method.

protected void clear() {
if(getCamera() != null) getCamera().resetViewMatrix();

GL11.glViewport(0, 0, EngineProperties.getScreenWidthi(), EngineProperties.getScreenHeighti());
GL30.glClearBuffer(GL11.GL_COLOR, 0, getColorBuffer().getBuffer());
GL30.glClearBuffer(GL11.GL_DEPTH, 0, getDepthBuffer().getBuffer());
    // Both the getColorBuffer() & getDepthBuffer() return a ColorBuffer object which is a wrapper for a FloatBuffer with color
    // oriented stuff, not much in it really, could use a normal FloatBuffer.
}


Thanks pointing me in the right direction, I had a clear before hand in an update method in the superclass, but I guess it was still at the wrong place :)