Problem with JOGL and Framebuffer Render-to-texture: Invalid Framebuffer Operation Error
- by quadelirus
Okay, so I am trying to render a scene to a small 32x32 texture and ran into problems. I get an "invalid framebuffer operation" error when I try to actually draw anything to the texture. I have simplified the code below so that it simply tries to render a quad to a texture and then bind that quad as a texture for another quad that is rendered to the screen. So my question is this... where is the error? This is using JOGL 1.1.1. The error occurs at Checkpoint2 in the code.
import java.awt.event.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.*;
import javax.swing.JFrame;
import java.nio.*;
public class Main extends JFrame implements GLEventListener, KeyListener, MouseListener, MouseMotionListener, ActionListener{
/* GL related variables */
private final GLCanvas canvas;
private GL gl;
private GLU glu;
private int winW = 600, winH = 600;
private int texRender_FBO;
private int texRender_RB;
private int texRender_32x32;
public static void main(String args[]) {
new Main();
}
/* creates OpenGL window */
public Main() {
super("Problem Child");
canvas = new GLCanvas();
canvas.addGLEventListener(this);
canvas.addKeyListener(this);
canvas.addMouseListener(this);
canvas.addMouseMotionListener(this);
getContentPane().add(canvas);
setSize(winW, winH);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
canvas.requestFocus();
}
/* gl display function */
public void display(GLAutoDrawable drawable) {
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, this.texRender_FBO);
gl.glPushAttrib(GL.GL_VIEWPORT_BIT);
gl.glViewport(0, 0, 32, 32);
gl.glClearColor(1.f, 0.f, 0.f, 1.f);
System.out.print("Checkpoint1: "); outputError();
gl.glBegin(GL.GL_QUADS);
{
//gl.glTexCoord2f(0.0f, 0.0f);
gl.glColor3f(1.f, 0.f, 0.f);
gl.glVertex3f(0.0f, 1.0f, 1.0f);
//gl.glTexCoord2f(1.0f, 0.0f);
gl.glColor3f(1.f, 1.f, 0.f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
//gl.glTexCoord2f(1.0f, 1.0f);
gl.glColor3f(1.f, 1.f, 1.f);
gl.glVertex3f(1.0f, 0.0f, 1.0f);
//gl.glTexCoord2f(0.0f, 1.0f);
gl.glColor3f(1.f, 0.f, 1.f);
gl.glVertex3f(0.0f, 0.0f, 1.0f);
}
gl.glEnd(); System.out.print("Checkpoint2: "); outputError(); //Here I get an invalid framebuffer operation
gl.glPopAttrib();
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
gl.glClearColor(0.f, 0.f, 0.f, 1.f);
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
gl.glColor3f(1.f, 1.f, 1.f);
gl.glBindTexture(GL.GL_TEXTURE_1D, this.texRender_32x32);
gl.glBegin(GL.GL_QUADS);
{
gl.glTexCoord2f(0.0f, 0.0f);
//gl.glColor3f(1.f, 0.f, 0.f);
gl.glVertex3f(0.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 0.0f);
//gl.glColor3f(1.f, 1.f, 0.f);
gl.glVertex3f(1.0f, 1.0f, 1.0f);
gl.glTexCoord2f(1.0f, 1.0f);
//gl.glColor3f(1.f, 1.f, 1.f);
gl.glVertex3f(1.0f, 0.0f, 1.0f);
gl.glTexCoord2f(0.0f, 1.0f);
//gl.glColor3f(1.f, 0.f, 1.f);
gl.glVertex3f(0.0f, 0.0f, 1.0f);
}
gl.glEnd();
}
/* initialize GL */
public void init(GLAutoDrawable drawable) {
gl = drawable.getGL();
glu = new GLU();
gl.glClearColor(.3f, .3f, .3f, 1f);
gl.glClearDepth(1.0f);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrtho(0, 1, 0, 1, -10, 10);
gl.glMatrixMode(GL.GL_MODELVIEW);
//Set up the 32x32 texture
this.texRender_FBO = genFBO(gl);
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, this.texRender_FBO);
this.texRender_32x32 = genTexture(gl);
gl.glBindTexture(GL.GL_TEXTURE_2D, this.texRender_32x32);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB_FLOAT32_ATI, 32, 32, 0, GL.GL_RGB, GL.GL_FLOAT, null);
gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, this.texRender_32x32, 0);
//gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT);
this.texRender_RB = genRB(gl);
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, this.texRender_RB);
gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, GL.GL_DEPTH_COMPONENT24, 32, 32);
gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT, this.texRender_RB);
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0);
outputError();
}
private void outputError() {
int c;
if ((c = gl.glGetError()) != GL.GL_NO_ERROR)
System.out.println(glu.gluErrorString(c));
}
private int genRB(GL gl) {
int[] array = new int[1];
IntBuffer ib = IntBuffer.wrap(array);
gl.glGenRenderbuffersEXT(1, ib);
return ib.get(0);
}
private int genFBO(GL gl) {
int[] array = new int[1];
IntBuffer ib = IntBuffer.wrap(array);
gl.glGenFramebuffersEXT(1, ib);
return ib.get(0);
}
private int genTexture(GL gl) {
final int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
return tmp[0];
}
/* mouse and keyboard callback functions */
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
winW = width;
winH = height;
gl.glViewport(0, 0, width, height);
}
//Sorry about these, I just had to delete massive amounts of code to boil this thing down and these are hangers-on
public void mousePressed(MouseEvent e) {}
public void mouseDragged(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void keyPressed(KeyEvent e) {}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) { }
public void keyTyped(KeyEvent e) { }
public void keyReleased(KeyEvent e) { }
public void mouseMoved(MouseEvent e) { }
public void actionPerformed(ActionEvent e) { }
public void mouseClicked(MouseEvent e) { }
public void mouseEntered(MouseEvent e) { }
public void mouseExited(MouseEvent e) { }
}