为什么glDrawBuffer会生成GL_INVALID_OPERATION



我有一个使用 OpenGL 3 到 JOGL 的 Java 应用程序,并且正在尝试实现多采样。我正在遵循本教程,到目前为止,它似乎可以工作,除了一行。当我调用gl.glBackBuffer(GL3.GL_BACK)时,它会生成一个GL_INVALID_OPERATION错误。如果程序继续,它似乎只绘制到一个缓冲区,无论它当前是前缓冲区还是后缓冲区,并在重绘时在所需的输出和垃圾数据之间切换。

根据文档:

如果默认帧缓冲受到影响,并且 buf 指示的缓冲区都不存在,则会生成GL_INVALID_OPERATION。

如果帧缓冲对象受到影响且 buf 不等于 GL_NONE 或 GL_COLOR_ATTACHMENT$m$,则生成 GL_INVALID_OPERATION,其中 $m$ 是介于 0 和 GL_MAX_COLOR_ATTACHMENTS 之间的值。

我不认为其中任何一个是我的问题,但其中一个必须是,因为它们是产生该错误的唯一场景。

以下是相关代码:

@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);
}

另外,我知道我没有做太多清理,但这应该不会影响这个问题。

编辑:根据要求,这是创建GLCanvas的代码:

    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);

我怀疑错误来自之前的调用。至少应该有很多错误,例如来自glDrawBuffer()调用之前的glBindFramebuffer()调用:

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");

multisampleFbo不是帧缓冲对象。它是这样创建的:

gl.glGenBuffers(1, pointer, 0);
multisampleFbo = pointer[0];

glGenBuffers()创建缓冲区对象,而不是帧缓冲区对象。要创建 FBO,您需要调用 glGenFramebuffers()

gl.glGenFramebuffers(1, pointer, 0);
multisampleFbo = pointer[0];

最新更新