Java tutorial
/** * Copyright 2013 Mark Browning, StellaArtois * Licensed under the LGPL 3.0 or later (See LICENSE.md for details) */ package com.mtbs3d.minecrift; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.OpenGlHelper; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.opengl.*; import org.lwjgl.util.glu.GLU; public class FBOParams { public static final Logger logger = LogManager.getLogger(); protected enum FBO_SUPPORT { USE_EXT_UNKNOWN, USE_GL30, USE_EXT, } int _textureType; protected static FBO_SUPPORT fboSupport = FBO_SUPPORT.USE_EXT_UNKNOWN; public FBOParams(String fboName, int textureType, int internalFormat, int baseFormat, int bufferType, int fboWidth, int fboHeight) throws Exception { Minecraft mc = Minecraft.getMinecraft(); _textureType = textureType; if (fboSupport == FBO_SUPPORT.USE_EXT_UNKNOWN) { // The framebuffer, which regroups 0, 1, or more textures, and 0 or 1 depth buffer. try { _frameBufferId = GL30.glGenFramebuffers(); fboSupport = FBO_SUPPORT.USE_GL30; } catch (IllegalStateException ex) { System.out.println( "[Minecrift] FBO creation: GL30.glGenFramebuffers not supported. Attempting to use EXTFramebufferObject.glGenFramebuffersEXT"); fboSupport = FBO_SUPPORT.USE_EXT; try { _frameBufferId = EXTFramebufferObject.glGenFramebuffersEXT(); } catch (IllegalStateException ex1) { System.out.println( "[Minecrift] FBO creation: EXTFramebufferObject.glGenFramebuffersEXT not supported, FBO creation failed."); throw ex1; } } } else if (fboSupport == FBO_SUPPORT.USE_GL30) { _frameBufferId = GL30.glGenFramebuffers(); } else { _frameBufferId = EXTFramebufferObject.glGenFramebuffersEXT(); } if (fboSupport == FBO_SUPPORT.USE_GL30) { _colorTextureId = GL11.glGenTextures(); _depthRenderBufferId = GL30.glGenRenderbuffers(); GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, _frameBufferId); checkGLError("FBO bind framebuffer"); GL11.glBindTexture(textureType, _colorTextureId); checkGLError("FBO bind texture"); GL11.glEnable(textureType); GL11.glTexParameterf(textureType, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); GL11.glTexParameterf(textureType, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); GL11.glTexImage2D(textureType, 0, internalFormat, fboWidth, fboHeight, 0, baseFormat, bufferType, (java.nio.ByteBuffer) null); System.out.println("[Minecrift] FBO '" + fboName + "': w: " + fboWidth + ", h: " + fboHeight); GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, textureType, _colorTextureId, 0); checkGLError("FBO bind texture framebuffer"); GL30.glBindRenderbuffer(GL30.GL_RENDERBUFFER, _depthRenderBufferId); // bind the depth renderbuffer GL30.glRenderbufferStorage(GL30.GL_RENDERBUFFER, GL14.GL_DEPTH_COMPONENT24, fboWidth, fboHeight); // get the data space for it GL30.glFramebufferRenderbuffer(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL30.GL_RENDERBUFFER, _depthRenderBufferId); checkGLError("FBO bind depth framebuffer"); } else { _colorTextureId = GL11.glGenTextures(); _depthRenderBufferId = EXTFramebufferObject.glGenRenderbuffersEXT(); EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _frameBufferId); checkGLError("FBO bind framebuffer"); GL11.glBindTexture(textureType, _colorTextureId); checkGLError("FBO bind texture"); GL11.glEnable(textureType); GL11.glTexParameterf(textureType, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); GL11.glTexParameterf(textureType, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); GL11.glTexImage2D(textureType, 0, internalFormat, fboWidth, fboHeight, 0, baseFormat, bufferType, (java.nio.ByteBuffer) null); System.out.println("[Minecrift] FBO '" + fboName + "': w: " + fboWidth + ", h: " + fboHeight); EXTFramebufferObject.glFramebufferTexture2DEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_COLOR_ATTACHMENT0_EXT, textureType, _colorTextureId, 0); checkGLError("FBO bind texture framebuffer"); EXTFramebufferObject.glBindRenderbufferEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, _depthRenderBufferId); // bind the depth renderbuffer EXTFramebufferObject.glRenderbufferStorageEXT(EXTFramebufferObject.GL_RENDERBUFFER_EXT, GL14.GL_DEPTH_COMPONENT24, fboWidth, fboHeight); // get the data space for it EXTFramebufferObject.glFramebufferRenderbufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, EXTFramebufferObject.GL_DEPTH_ATTACHMENT_EXT, EXTFramebufferObject.GL_RENDERBUFFER_EXT, _depthRenderBufferId); checkGLError("FBO bind depth framebuffer"); } if (!checkFramebufferStatus()) { // OK, if we have an error here - then throw an exception System.out.println("[Minecrift] FAILED to create framebuffer!!"); throw new Exception("Failed to create framebuffer"); } } public void bindRenderTarget() { if (fboSupport == FBO_SUPPORT.USE_GL30) GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, _frameBufferId); else EXTFramebufferObject.glBindFramebufferEXT(EXTFramebufferObject.GL_FRAMEBUFFER_EXT, _frameBufferId); } public void bindTexture() { OpenGlHelper.setActiveTexture(GL13.GL_TEXTURE0); GL11.glBindTexture(_textureType, _colorTextureId); } public void bindTexture_Unit1() { OpenGlHelper.setActiveTexture(GL13.GL_TEXTURE1); GL11.glBindTexture(_textureType, _colorTextureId); } public int getColorTextureId() { return _colorTextureId; } public void delete() { if (_depthRenderBufferId != -1) { if (fboSupport == FBO_SUPPORT.USE_GL30) GL30.glDeleteRenderbuffers(_depthRenderBufferId); else EXTFramebufferObject.glDeleteRenderbuffersEXT(_depthRenderBufferId); _depthRenderBufferId = -1; } if (_colorTextureId != -1) { GL11.glDeleteTextures(_colorTextureId); _colorTextureId = -1; } if (_frameBufferId != -1) { if (fboSupport == FBO_SUPPORT.USE_GL30) GL30.glDeleteFramebuffers(_frameBufferId); else EXTFramebufferObject.glDeleteFramebuffersEXT(_frameBufferId); _frameBufferId = -1; } } // check FBO completeness public static boolean checkFramebufferStatus() { // check FBO status int status = ARBFramebufferObject.glCheckFramebufferStatus(ARBFramebufferObject.GL_FRAMEBUFFER); switch (status) { case ARBFramebufferObject.GL_FRAMEBUFFER_COMPLETE: System.out.println("[Minecrift] Framebuffer complete."); return true; case ARBFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: System.out.println("[ERROR] Framebuffer incomplete: Attachment is NOT complete."); return false; case ARBFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: System.out.println("[ERROR] Framebuffer incomplete: No image is attached to FBO."); return false; // case GL30.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: // System.out.println("[ERROR] Framebuffer incomplete: Attached images have different dimensions."); // return false; // // case ARBFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_FORMATS: // System.out.println("[ERROR] Framebuffer incomplete: Color attached images have different internal formats."); // return false; case ARBFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: System.out.println("[ERROR] Framebuffer incomplete: Draw buffer."); return false; case ARBFramebufferObject.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: System.out.println("[ERROR] Framebuffer incomplete: Read buffer."); return false; case ARBFramebufferObject.GL_FRAMEBUFFER_UNSUPPORTED: System.out.println("[ERROR] Framebuffer incomplete: Unsupported by FBO implementation."); return false; default: System.out.println("[ERROR] Framebuffer incomplete: Unknown error."); return false; } } /** * Checks for an OpenGL error. If there is one, prints the error ID and error string. */ public void checkGLError(String par1Str) { int i = GL11.glGetError(); if (i != 0) { String s1 = GLU.gluErrorString(i); logger.error("########## GL ERROR ##########"); logger.error("@ " + par1Str); logger.error(i + ": " + s1); } } int _frameBufferId = -1; int _colorTextureId = -1; int _depthRenderBufferId = -1; }