У меня есть приложение Java, использующее OpenGL 3 через JOGL, и пытаюсь реализовать мультисэмплинг. Я следую this учебному пособию, и до сих пор он работает, за исключением одной строки. Когда я звоню gl.glBackBuffer(GL3.GL_BACK)
, он генерирует ошибку GL_INVALID_OPERATION
. Если программа продолжается, она, как представляется, обращается только к одному буферу, независимо от того, является ли она в настоящее время фронт- или обратным буфером, и переключается между желаемым выходом и данными мусора всякий раз, когда он перерисовывается.Почему glDrawBuffer генерирует GL_INVALID_OPERATION?
Согласно документации:
GL_INVALID_OPERATION генерируется, если фреймбуфера по умолчанию влияет и ни один из буферов не указано ЬиЕ существует.
GL_INVALID_OPERATION генерируется, если объект фреймбуфера затронут, а 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.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);
}
Кроме того, я знаю, что я не сделал много очистки, но это не должно повлиять на эту проблему.
EDIT: В соответствии с просьбой, вот код, в котором создается 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);
Является ли ваш стандартный фреймбуфер двойной буферизацией? Симптомы предполагают, что вы можете использовать один буферный фреймбуфер. –
У вас даже есть двойной буферизированный фреймбуфер? Обратите внимание, что 'gl.glEnable (GL3.GL_DOUBLEBUFFER);' недопустимо и не будет создавать его. – derhass
Я не уверен, но, похоже, он имеет двойную буферизацию, так как изображение переключается между желаемым результатом и данными мусора при его обновлении. Это означает, что должны быть два буфера, один из которых нарисован. Поправьте меня, если я ошибаюсь, я все еще учусь. – Ontonator