package net.krazyweb.opengl;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import net.krazyweb.renderer.Renderer.TEXTURE_TYPE;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
public class OpenGLFBO {
private int fbo;
private int texNum = 0;
private int width, height;
protected int[] textures;
private static final int[] COLOR_ATTACHMENTS = new int[] {
GL30.GL_COLOR_ATTACHMENT0,
GL30.GL_COLOR_ATTACHMENT1,
GL30.GL_COLOR_ATTACHMENT2,
GL30.GL_COLOR_ATTACHMENT3
};
public OpenGLFBO(int w, int h, int numberOfTextures) {
width = w;
height = h;
fbo = GL30.glGenFramebuffers();
textures = new int[numberOfTextures];
for (int i = 0; i < numberOfTextures; i++) {
textures[i] = GL11.glGenTextures();
}
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo);
}
protected void addTexture(TEXTURE_TYPE type) {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textures[texNum]);
switch (type) {
case RGB:
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (ByteBuffer) null);
break;
case RGBA16F:
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL30.GL_RGBA16F, width, height, 0, GL11.GL_RGBA, GL11.GL_FLOAT, (FloatBuffer) null);
break;
case RGBA32F:
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL30.GL_RGBA32F, width, height, 0, GL11.GL_RGBA, GL11.GL_FLOAT, (FloatBuffer) null);
break;
}
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);
texNum++;
}
protected void finalize() {
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);
int[] attachments = new int[textures.length];
for (int i = 0; i < textures.length; i++) {
GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, COLOR_ATTACHMENTS[i], GL11.GL_TEXTURE_2D, textures[i], 0);
attachments[i] = COLOR_ATTACHMENTS[i];
}
IntBuffer buffer = BufferUtils.createIntBuffer(textures.length);
buffer.put(attachments);
buffer.flip();
GL20.glDrawBuffers(buffer);
int status = GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER);
if (status != GL30.GL_FRAMEBUFFER_COMPLETE) {
System.out.println("Framebuffer error.");
}
}
protected void enable() {
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fbo);
GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT);
GL11.glViewport(0, 0, width, height);
}
}