Почему glDrawBuffer генерирует GL_INVALID_OPERATION?

У меня есть приложение Java, использующее OpenGL 3 через JOGL, и пытаюсь реализовать мультисэмплинг. Я следую этому руководству, и до сих пор он работает, за исключением одной строки. Когда слово gl.glBackBuffer(GL3.GL_BACK), он генерирует GL_INVALID_OPERATION ошибку. Если программа продолжается, она, как представляется, обращается только к одному буферу, независимо от того, является ли она в настоящее время front- или обратным буфером, и переключается между желаемым выходом и данными мусора всякий раз, когда он перерисовывается.

Согласно документации:

GL_INVALID_OPERATION генерируется, если поврежден фреймбуфер по умолчанию, и ни один из буферов, обозначенных buf, не существует.

GL_INVALID_OPERATION генерируется, если объект framebuffer затронут, а buf не равен GL_NONE или GL_COLOR_ATTACHMENT $ m $, где $ 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.*****************(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);

}

Кроме того, я знаю, что не сделал много очистки, но это не должно повлиять на эту проблему.

EDIT: в соответствии с запросом, вот код, в котором создается GLCanvas:

glp = GLProfile.get("GL3");
 caps = new GLCapabilities(glp);
 caps.*****************(true);
 canvas = new GLCanvas(caps);
 canvas.setPreferredSize(new Dimension(800, 600));
 canvas.addGLEventListener(glListener);

 frame.add(canvas);
1 ответ

Я подозреваю, что ошибка исходит из более раннего вызова. По крайней мере, должно быть множество ошибок, например, из glBindFramebuffer() непосредственно предшествующего glDrawBuffer():

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

licensed under cc by-sa 3.0 with attribution.