/***********************************************************************
* mt4j Copyright (c) 2008 - 2010 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
***********************************************************************/
package org.mt4j.util.opengl;
import java.util.Stack;
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Logger;
import org.apache.log4j.SimpleLayout;
/**
* The FBO stack manages the current opengl drawing target. It allows to switch drawing to/from different
* frame buffer objects.
* Usage:<br>
* <br>GLFboStack.getInstance(gl).pushFBO(); //saves the current render target/frame buffer
* <br>GLFboStack.getInstance(gl).useFBO(glFBO); //changes to another frame buffer
* <br>GLFboStack.getInstance(gl).popFBO() //switches back to the previously saved frame buffer
* @author Christopher Ruff
*/
public class GLFboStack{
/** The Constant logger. */
private static final Logger logger = Logger.getLogger(GLFboStack.class.getName());
static{
// logger.setLevel(Level.ERROR);
SimpleLayout l = new SimpleLayout();
ConsoleAppender ca = new ConsoleAppender(l);
logger.addAppender(ca);
}
/** The gl. */
public GL gl;
/** The current fbo. */
protected int currentFBO;
/** The fbo name stack. */
protected Stack<Integer> fboNameStack;
/** The instance. */
private static GLFboStack instance = null;
/**
* Instantiates a new gL fbo stack.
* @param gl the gl
*/
private GLFboStack(GL gl){
this.gl = gl;
fboNameStack = new Stack<Integer>();
currentFBO = 0;
}
/**
* Gets the single instance of GLFboStack.
*
* @return single instance of GLFboStack
*/
public static GLFboStack getInstance(){
if (instance == null){
instance = new GLFboStack(GLU.getCurrentGL());
return instance;
}else{
return instance;
}
}
/**
* Pushes the currently used render target ID on the stack.
*/
public void pushFBO(){
fboNameStack.push(new Integer(currentFBO));
}
/**
* Binds the specified render target ID and sets it as current.
*
* @param fbo the fbo
*/
public void useFBO(int fbo){
currentFBO = fbo;
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, currentFBO);
}
/**
* Binds the specified frame buffer object and sets it as current.
*
* @param fbo the fbo
*/
public void useFBO(GLFBO fbo){
currentFBO = fbo.getName();
fbo.bind();
}
/**
* Peek fbo.
*
* @return the int
*/
public int peekFBO(){
if (fboNameStack.isEmpty()){
return 0;
}else{
// return fboNameStack.peek();
return currentFBO;
}
}
//NOTE THIS UNBINDS A CURRENT FBO IF SET! -> no need for calling unbind()!
/**
* Pops the fbo.
* This switches back (binds) to the formely pushed fbo.
* <br>NOTE: THIS UNBINDS A CURRENT FBO IF SET! -> no need for calling unbind()!
*/
public void popFBO(){
if (fboNameStack.isEmpty()){
logger.error("Trying to pop() from an empty framebuffer stack!"); //TODO -> just bind 0 !?
}else{
currentFBO = fboNameStack.pop().intValue();
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, currentFBO);
}
}
}