package electrosphere.renderer.framebuffer; import electrosphere.engine.Globals; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.texture.Texture; import java.nio.IntBuffer; import org.lwjgl.BufferUtils; import static org.lwjgl.opengl.GL11.GL_DEPTH_COMPONENT; import static org.lwjgl.opengl.GL11.GL_FLOAT; import static org.lwjgl.opengl.GL11.GL_LINEAR; import static org.lwjgl.opengl.GL11.GL_NEAREST; import static org.lwjgl.opengl.GL11.GL_NONE; import static org.lwjgl.opengl.GL11.GL_RED; import static org.lwjgl.opengl.GL11.GL_RGB; import static org.lwjgl.opengl.GL11.GL_RGBA; import static org.lwjgl.opengl.GL11.GL_SHORT; 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.GL12.GL_CLAMP_TO_EDGE; import static org.lwjgl.opengl.GL13.GL_CLAMP_TO_BORDER; 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_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_RENDERBUFFER; import static org.lwjgl.opengl.GL30.GL_HALF_FLOAT; import static org.lwjgl.opengl.GL30.glBindRenderbuffer; import static org.lwjgl.opengl.GL30.glFramebufferRenderbuffer; import static org.lwjgl.opengl.GL30.glGenRenderbuffers; import static org.lwjgl.opengl.GL30.glRenderbufferStorage; import static org.lwjgl.opengl.GL45.glNamedFramebufferDrawBuffer; import static org.lwjgl.opengl.GL45.glNamedFramebufferDrawBuffers; import static org.lwjgl.opengl.GL45.glNamedFramebufferReadBuffer; /** * Utilities for framebuffer creation */ public class FramebufferUtils { public static Texture generateScreenTextureColor(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_RGB, GL_UNSIGNED_BYTE); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); //these make sure the texture actually clamps to the borders of the quad texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texture.checkStatus(openGLState); return texture; } public static Texture generateScreenTextureColorAlpha(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_UNSIGNED_BYTE); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); //these make sure the texture actually clamps to the borders of the quad texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texture.checkStatus(openGLState); return texture; } public static Texture generateScreenTextureDepth(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_FLOAT); texture.checkStatus(openGLState); return texture; } public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture, Texture depthTexture){ Framebuffer buffer = new Framebuffer(); //texture // int texture = glGenTextures(); // glBindTexture(GL_TEXTURE_2D,texture); // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // //these make sure the texture actually clamps to the borders of the quad // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //bind texture to fbo buffer.setMipMapLevel(0); buffer.attachTexture(openGLState,colorTexture); buffer.setDepthAttachment(openGLState,depthTexture.getTexturePointer()); //check make sure compiled buffer.checkStatus(); return buffer; } public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture){ Framebuffer buffer = new Framebuffer(); //texture // int texture = glGenTextures(); // glBindTexture(GL_TEXTURE_2D,texture); // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // //these make sure the texture actually clamps to the borders of the quad // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); //bind texture to fbo buffer.setMipMapLevel(0); buffer.attachTexture(openGLState,colorTexture.getTexturePointer()); //check make sure compiled buffer.checkStatus(); return buffer; } public static Framebuffer generateScreensizeTextureFramebuffer(OpenGLState openGLState){ Framebuffer buffer = new Framebuffer(); buffer.bind(openGLState); //texture Texture texture = new Texture(); texture.glTexImage2D(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); //these make sure the texture actually clamps to the borders of the quad texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texture.checkStatus(openGLState); //bind texture to fbo buffer.setMipMapLevel(0); buffer.attachTexture(openGLState,texture); //renderbuffer int renderBuffer = glGenRenderbuffers(); glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); //bind rbo to fbo glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer); //check make sure compiled buffer.checkStatus(); return buffer; } public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height){ Framebuffer buffer = new Framebuffer(); buffer.bind(openGLState); //texture Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_UNSIGNED_BYTE); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); //these make sure the texture actually clamps to the borders of the quad texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); texture.checkStatus(openGLState); //bind texture to fbo buffer.setMipMapLevel(0); buffer.attachTexture(openGLState,texture); //renderbuffer int renderBuffer = glGenRenderbuffers(); glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); //bind rbo to fbo glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer); //check make sure compiled buffer.checkStatus(); return buffer; } public static Renderbuffer generateScreensizeStencilDepthRenderbuffer(OpenGLState openGLState){ Renderbuffer buffer = new Renderbuffer(); buffer.bind(); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); Globals.renderingEngine.checkError(); return buffer; } static int depthMapWidth = 4096; static int depthMapHeight = 4096; public static Framebuffer generateDepthBuffer(OpenGLState openGLState){ Framebuffer buffer = new Framebuffer(); buffer.bind(openGLState); //texture Texture texture = new Texture(); texture.glTexImage2D(openGLState, depthMapWidth, depthMapHeight, GL_DEPTH_COMPONENT, GL_FLOAT); texture.setMinFilter(GL_NEAREST); texture.setMagFilter(GL_NEAREST); texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); texture.setBorderColor(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f }); texture.checkStatus(openGLState); //bind texture to fbo buffer.setMipMapLevel(0); buffer.setDepthAttachment(openGLState,texture.getTexturePointer()); glNamedFramebufferDrawBuffer(buffer.getFramebufferPointer(), GL_NONE); glNamedFramebufferReadBuffer(buffer.getFramebufferPointer(), GL_NONE); //check make sure compiled buffer.checkStatus(); return buffer; } public static Texture generateDepthBufferTexture(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_SHORT); texture.setMinFilter(GL_NEAREST); texture.setMagFilter(GL_NEAREST); texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); texture.setBorderColor(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f }); texture.checkStatus(openGLState); return texture; } public static Framebuffer generateDepthBuffer(OpenGLState openGLState, int width, int height, Texture texture){ Framebuffer buffer = new Framebuffer(); buffer.bind(openGLState); //bind texture to fbo buffer.setMipMapLevel(0); buffer.setDepthAttachment(openGLState,texture.getTexturePointer()); glNamedFramebufferDrawBuffer(buffer.getFramebufferPointer(), GL_NONE); glNamedFramebufferReadBuffer(buffer.getFramebufferPointer(), GL_NONE); //check make sure compiled buffer.checkStatus(); return buffer; } public static Texture generateOITAccumulatorTexture(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_HALF_FLOAT); texture.checkStatus(openGLState); return texture; } public static Texture generateOITRevealageTexture(OpenGLState openGLState, int width, int height){ Texture texture = new Texture(); texture.setMinFilter(GL_LINEAR); texture.setMagFilter(GL_LINEAR); texture.glTexImage2D(openGLState, width, height, GL_RED, GL_FLOAT); texture.checkStatus(openGLState); return texture; } public static Framebuffer generateOITFramebuffer(OpenGLState openGLState, int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture){ Framebuffer buffer = new Framebuffer(); buffer.bind(openGLState); //bind texture to fbo buffer.setMipMapLevel(0); buffer.attachTexture(openGLState,accumulatorTex.getTexturePointer(),0); buffer.attachTexture(openGLState,revealageTex.getTexturePointer(),1); buffer.setDepthAttachment(openGLState,depthTexture.getTexturePointer()); // const GLenum transparentDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; // glDrawBuffers(2, transparentDrawBuffers); IntBuffer drawBuffers = BufferUtils.createIntBuffer(2); drawBuffers.put(GL_COLOR_ATTACHMENT0); drawBuffers.put(GL_COLOR_ATTACHMENT1); drawBuffers.flip(); glNamedFramebufferDrawBuffers(buffer.getFramebufferPointer(),drawBuffers); //check make sure compiled buffer.checkStatus(); return buffer; } }