I am attempting to follow ThinMatrix's water tutorial. To do this, I need to create an FBO and render it as a texture.
However as you can see, the water is completely black:
I am using the source code provided directly from the tutorial (copied from the link).
Basically, I create a FrameBuffer:
public FrameBufferObject() {//call when loading the game
initialiseReflectionFrameBuffer();
initialiseRefractionFrameBuffer(); //Let's ignore refraction for now, as I only use reflection at the moment.
}
private void initialiseReflectionFrameBuffer() {
reflectionFrameBuffer = createFrameBuffer();
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
reflectionDepthBuffer = createDepthBufferAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
unbindCurrentFrameBuffer();
}
I then create a texture attachment:
private int createTextureAttachment( int width, int height) {
int texture = GL11.glGenTextures();
GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL32.glFramebufferTexture(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0,
texture, 0);
return texture;
}
And I also create a depth buffer attachment:
private int createDepthBufferAttachment(int width, int height) {
int depthBuffer = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBuffer);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL11.GL_DEPTH_COMPONENT, width,
height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT,
GL30.GL_RENDERBUFFER, depthBuffer);
return depthBuffer;
}
Then, I am rendering the objects to the frame buffer object:
Main.TerrainDemo.shader.start();
fbos.bindReflectionFrameBuffer();
for (Grass g : Main.TerrainDemo.toDraw){
g.render();
}
fbos.unbindCurrentFrameBuffer();
I bind the frame buffer like this:
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
The "error" when I print out glGetError() is a normal 0
. The "frame buffer setup" message does print out.
After which, I expect that calling fbos.getReflectionTexture()
would return a texture ID... And it does! It successfully returns texture ID 12. However, the texture when I bind it is completely black.
public int getReflectionTexture() {//get the resulting texture
return reflectionTexture; //Remember, this was our original texture attachment.
}
reflectionTexture = createTextureAttachment(REFLECTION_WIDTH,REFLECTION_HEIGHT);
I am unable to work out what is wrong, and why the texture is not displaying anything rendered to it.
Things I know are not wrong:
I am definitely drawing and texturing the water itself correctly. I can use any pre-loaded texture and texture the water just fine:
Also, Objects being rendered to the FBO have the correct translations, rotations, etc. If I don't bind any framebuffer, the foliage intended for the FBO is drawn (and seen) on my screen correctly.
So i realise this is a super old question that probably nobody cares about anymore, but i recently found myself here after doing the same tutorial and having similar problems.
After exercising a bit of google foo, i realised i had made a very basic error in my code that could be the same solution.
I simply wasn't doing;
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
while is was the frame buffer object being used, before filling it up again:
I just went ahead and put it at the end of the bind frame buffer function and i worked!
private void bindFrameBuffer(int frameBuffer, int width, int height){
GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBuffer);
GL11.glViewport(0, 0, width, height);
System.out.println("Bound");
if(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) == GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Frame buffer setup is complete: " + GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
}
System.out.println("Error: " + GL11.glGetError());
}
Might not be the same problem as my error was particularly basic, but worth a try.
Does anyone know if this solution is correct, or is it a band aid over a larger problem?