Reputation: 248
I've three images which I'm trying to render with my SpriteBatch and FrameBuffer.
These are the steps I'm doing.
Here's some facts I know about the this problem
Here's how it's supposed to look like
Here's how it's looking with my framebuffer.
Here's how it's looking with my framebuffer and drawing the first texture two times. Still missing the other two textures. Position in not the problem.
Here's the code for my FrameBuffer :
// Stencil is broken currently broken, in my example. I'm not using any stencil buffers.
public FrameBuffer(int width, int height, boolean hasDepth, boolean hasStencil) {
this.width = width;
this.height = height;
frameBufferID = GL30.glGenFramebuffers();
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
if (hasDepth && hasStencil) {
int depthAndStencilBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthAndStencilBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_DEPTH24_STENCIL8, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_STENCIL_ATTACHMENT, GL30.GL_RENDERBUFFER, depthAndStencilBufferID);
}
else if (hasDepth) {
int depthBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, depthBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_DEPTH_COMPONENT32F, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, depthBufferID);
}
else if (hasStencil) {
int stencilBufferID = GL30.glGenRenderbuffers();
GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, stencilBufferID);
GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL30.GL_STENCIL_INDEX16, width, height);
GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_STENCIL_ATTACHMENT, GL30.GL_RENDERBUFFER, stencilBufferID);
}
colorTexture = new Texture(width, height);
colorTexture.bind();
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, colorTexture.getTextureID(), 0);
int result = GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
//error handling
RenderUtil.unbindFrameBuffer();
}
private Texture colorTexture;
private int width, height;
private int frameBufferID, depthBufferID, stencilBufferID;
public void begin () {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
GL11.glViewport(0, 0, width, height);
}
public void end () {
GL11.glViewport(0, 0, RenderingEngine.getWidth(), RenderingEngine.getHeight());
RenderUtil.unbindFrameBuffer();
RenderUtil.unbindTextures();
}
public Texture getColorTexture () {
return colorTexture;
}
public int getWidth () {
return width;
}
public int getHeight () {
return height;
}
Here's how I create a Texture if it's to any use :
private void loadTexture (ByteBuffer buffer, int textureID, int width, int height) {
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA8, width, width, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
}
There seems to be a problem in my SpriteBatch when switching texture. Here's how the switching works. I remind you, using my SpriteBatch to render to the screen gives my the wanted result. But rendering to a FrameBuffer doesn't work.
`
public void flush () {
flushes++;
buffer.flip();
MESH.setVertices(buffer);
if (lastTexture != null) {
lastTexture.bind();
}
MESH.draw();
buffer.clear();
}
/** Begins the SpriteBatch. */
public void begin () {
if (rendering) {
new IllegalStateException("You have to SpriteBatch.end() before calling begin again!").printStackTrace();
}
flushes = 0;
rendering = true;
shader.bind();
shader.setUniformMat4f("projection", camera.getCombined());
shader.setUniformVec4("color", color);
}
/** Ends the SpriteBatch, also flushes it. */
public void end () {
if (!rendering) {
new IllegalStateException("You've to SpriteBatch.begin before ending the spritebatch").printStackTrace();
}
rendering = false;
flush();
RenderUtil.unbindShaders();
RenderUtil.unbindTextures();
}
/** Switches the textures and flushes the old one.
* @param t */
private void switchTextures (Texture t) {
if (lastTexture != null) {
flush();
}
lastTexture = t;
}
` Going to create a small example. Should be up soon.
EDIT: Problem wasn't my FrameBuffer. Was my SpriteBatch.
Upvotes: 0
Views: 1267
Reputation: 43369
You need to clear your buffers while your FBO is bound, otherwise you're only clearing the color/stencil/depth buffer associated with your window. That is not the behavior you want, because the depth test in this scenario uses your FBO's depth rather than the window's (default framebuffer).
public void begin ()
is the most logical place to do this:public void begin () {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferID);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);
GL11.glViewport(0, 0, width, height);
}
Upvotes: 3