package Graphics;
import static org.lwjgl.opengl.GL11.GL_BLEND;
import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_NO_ERROR;
import static org.lwjgl.opengl.GL11.GL_ONE;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_REPEAT;
import static org.lwjgl.opengl.GL11.GL_RGBA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
import static org.lwjgl.opengl.GL11.GL_ZERO;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glClear;
import static org.lwjgl.opengl.GL11.glClearColor;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glGenTextures;
import static org.lwjgl.opengl.GL11.glGetError;
import static org.lwjgl.opengl.GL11.glGetInteger;
import static org.lwjgl.opengl.GL11.glTexImage2D;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL11.glViewport;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL14.GL_FUNC_ADD;
import static org.lwjgl.opengl.GL14.glBlendFuncSeparate;
import static org.lwjgl.opengl.GL14.glBlendEquation;
import static org.lwjgl.opengl.GL20.glDrawBuffers;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT0;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT1;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT2;
import static org.lwjgl.opengl.GL30.GL_DEPTH24_STENCIL8;
import static org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL_ATTACHMENT;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_COMPLETE;
import static org.lwjgl.opengl.GL30.GL_MAX_COLOR_ATTACHMENTS;
import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER;
import static org.lwjgl.opengl.GL30.GL_RGBA32F;
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;
import static org.lwjgl.opengl.GL30.glFramebufferRenderbuffer;
import static org.lwjgl.opengl.GL30.glFramebufferTexture2D;
import static org.lwjgl.opengl.GL30.glGenFramebuffers;
import static org.lwjgl.opengl.GL30.glGenRenderbuffers;
import static org.lwjgl.opengl.GL30.glRenderbufferStorage;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.util.vector.Vector4f;
public class RenderTarget {
private int fboId, colorId, normalId, positionId, depthId;
private Vector4f clearColor;
public RenderTarget(boolean multiChannel, boolean isLight)
{
this.clearColor = new Vector4f(0.0f, 0.0f, 0.0f, 1.0f);
//init and bind
this.fboId = glGenFramebuffers();
this.colorId = glGenTextures();
if(multiChannel)
{
this.normalId = glGenTextures();
this.positionId = glGenTextures();
}
this.depthId = glGenRenderbuffers();
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
//set up texture
addAttachment(colorId, 0, true);
if(multiChannel)
{
addAttachment(normalId, 1, false);
addAttachment(positionId, 2, false);
}
//set up depth buffer
glBindRenderbuffer(GL_RENDERBUFFER, depthId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 800, 600);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthId);
IntBuffer temp = BufferUtils.createIntBuffer(16);
glGetInteger(GL_MAX_COLOR_ATTACHMENTS, temp);
if(temp.get(0) < 4)
{
System.out.println("ERROR: Support for color attachments is not sufficient. Fuggg.");
}
IntBuffer drawBuf = BufferUtils.createIntBuffer(3);
drawBuf.put(GL_COLOR_ATTACHMENT0);
if(multiChannel)
{
drawBuf.put(GL_COLOR_ATTACHMENT1);
drawBuf.put(GL_COLOR_ATTACHMENT2);
}
//FLIP IT OR YOU DIE
drawBuf.flip();
glDrawBuffers(drawBuf);
//error checking
int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
System.out.println("Error " + status + " in frame buffer object generation");
}
int lkj = glGetError();
if( lkj != GL_NO_ERROR )
{
throw new RuntimeException("OpenGL error: "+org.lwjgl.util.glu.GLU.gluErrorString(lkj));
}
//unbind fbo
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
private void addAttachment(int id, int attachmentNo, boolean integerRgba)
{
glBindTexture(GL_TEXTURE_2D, id);
//set params
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//initialize size
if(integerRgba)
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 600, 0,GL_RGBA, GL_UNSIGNED_BYTE, (java.nio.ByteBuffer) null);
}
else
{
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 800, 600, 0, GL_RGBA, GL_FLOAT, (java.nio.ByteBuffer) null);
}
//attach to fbo
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachmentNo, GL_TEXTURE_2D, id, 0);
//clear
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//unbind here?
}
protected void set()
{
glBindTexture(GL_TEXTURE_2D, 0);//unbind texture
glBindFramebuffer(GL_FRAMEBUFFER, fboId);//bind fbo
glViewport(0,0,800,600);//set to our texture size. adjust this later depending on the resolution and view size
//clear it
glClearColor(clearColor.x, clearColor.y, clearColor.z, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
protected void unset()
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
protected int getColId()
{
return colorId;
}
protected int getNormId()
{
return normalId;
}
protected int getPosId()
{
return positionId;
}
protected FloatBuffer genFloatBuffer(float[] input)
{
FloatBuffer fbuff = null;
try{
fbuff = BufferUtils.createFloatBuffer(input.length);
fbuff.put(input);
fbuff.rewind();
}
catch (Exception e)
{
System.out.println(e);
return null;
}
return fbuff;
}
}