I have a Java application using OpenGL 3 through JOGL, and am trying to implement multi-sampling. I am following this tutorial, and so far, it seems to work, except for one line. When I call gl.glBackBuffer(GL3.GL_BACK)
, it generates a GL_INVALID_OPERATION
error. If the program continues, it appears to draw to only one buffer, regardless of whether it is currently the front- or the back-buffer, and switches between the desired output and garbage data whenever it is redrawn.
According to the documentation:
GL_INVALID_OPERATION is generated if the default framebuffer is affected and none of the buffers indicated by buf exists.
GL_INVALID_OPERATION is generated if a framebuffer object is affected and buf is not equal to GL_NONE or GL_COLOR_ATTACHMENT$m$, where $m$ is a value between 0 and GL_MAX_COLOR_ATTACHMENTS.
I don't think that either of these is my problem, but one of them must be, because they are the only scenarios in which that error is generated.
Here is the relevant code:
@Override
public void init(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
int[] pointer = new int[1];
sl = new ShaderLoader();
sl.loadShader(gl);
gl.glEnable(GL3.GL_DOUBLEBUFFER);
gl.glEnable(GL3.GL_MULTISAMPLE);
gl.glClearColor(1, 1, 1, 1);
gl.glGenTextures(1, pointer, 0);
multisampleTex = pointer[0];
gl.glGenBuffers(1, pointer, 0);
multisampleFbo = pointer[0];
gl.glGenRenderbuffers(1, pointer, 0);
multisampleRbo = pointer[0];
main.init(drawable);
gl.glGetIntegerv(GL3.GL_MAX_SAMPLES, pointer, 0);
System.out.println(pointer[0]);
}
@Override
public void dispose(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
sl.destroy(gl);
}
@Override
public void display(GLAutoDrawable drawable) {
// GL3 gl = new DebugGL3(drawable.getGL().getGL3());
GL3 gl = drawable.getGL().getGL3();
// drawable.setGL(gl);
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, multisampleFbo);
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
main.render(drawable);
gl.glBindFramebuffer(GL3.GL_DRAW_FRAMEBUFFER, GL3.GL_NONE);
gl.glBindFramebuffer(GL3.GL_READ_FRAMEBUFFER, multisampleFbo);
checkGLError();
gl.glDrawBuffer(GL3.GL_BACK); // Throws GL_INVALID_OPERATION
checkGLError("OpenGL error at glDrawBuffer: 0x%h%n");
gl.glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
GL3.GL_COLOR_BUFFER_BIT, GL3.GL_NEAREST);
checkGLError();
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width,
int height) {
GL3 gl = drawable.getGL().getGL3();
this.width = width;
this.height = height;
updateMultisampleObjects(gl);
gl.glViewport(0, 0, width, height);
updatePMatrix();
}
private void updateMultisampleObjects(GL3 gl) {
gl.glBindTexture(GL3.GL_TEXTURE_2D_MULTISAMPLE, multisampleTex);
gl.glTexImage2DMultisample(GL3.GL_TEXTURE_2D_MULTISAMPLE,
NUM_OF_SAMPLES, GL3.GL_RGBA8, width, height, true);
gl.glBindFramebuffer(GL3.GL_FRAMEBUFFER, multisampleFbo);
gl.glFramebufferTexture2D(GL3.GL_FRAMEBUFFER, GL3.GL_COLOR_ATTACHMENT0,
GL3.GL_TEXTURE_2D_MULTISAMPLE, multisampleTex, 0);
gl.glBindRenderbuffer(GL3.GL_RENDERBUFFER, multisampleRbo);
gl.glRenderbufferStorageMultisample(GL3.GL_RENDERBUFFER,
NUM_OF_SAMPLES, GL3.GL_DEPTH24_STENCIL8, width, height);
gl.glFramebufferRenderbuffer(GL3.GL_FRAMEBUFFER,
GL3.GL_DEPTH_STENCIL_ATTACHMENT, GL3.GL_RENDERBUFFER,
multisampleRbo);
}
Also, I know I haven't done much cleanup, but that should not impact this problem.
EDIT: As requested, here is the code where the GLCanvas is created:
glp = GLProfile.get("GL3");
caps = new GLCapabilities(glp);
caps.setDoubleBuffered(true);
canvas = new GLCanvas(caps);
canvas.setPreferredSize(new Dimension(800, 600));
canvas.addGLEventListener(glListener);
frame.add(canvas);