/*******************************************************************************
* Breakout Cave Survey Visualizer
*
* Copyright (C) 2014 James Edwards
*
* jedwards8 at fastmail dot fm
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*******************************************************************************/
package org.andork.jogl;
import static com.jogamp.opengl.GL.GL_COLOR_ATTACHMENT0;
import static com.jogamp.opengl.GL.GL_DEPTH_ATTACHMENT;
import static com.jogamp.opengl.GL.GL_DEPTH_COMPONENT32;
import static com.jogamp.opengl.GL.GL_FRAMEBUFFER;
import static com.jogamp.opengl.GL.GL_RENDERBUFFER;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL3;
public class GL3Framebuffer implements GL3Resource {
private long lastDisplay;
private int maxNumSamples = 0;
private int currentNumSamples = 1;
private int renderingFboWidth;
private int renderingFboHeight;
private int renderingFbo = -1;
private int renderingColorBuffer = -1;
private int renderingDepthBuffer = -1;
private void destroyOffscreenBuffers(GL3 gl) {
int[] temps = new int[1];
if (renderingFbo >= 0) {
temps[0] = renderingFbo;
gl.glDeleteFramebuffers(1, temps, 0);
renderingFbo = -1;
}
if (renderingColorBuffer >= 0) {
temps[0] = renderingColorBuffer;
gl.glDeleteRenderbuffers(1, temps, 0);
renderingColorBuffer = -1;
}
if (renderingDepthBuffer >= 0) {
temps[0] = renderingDepthBuffer;
gl.glDeleteRenderbuffers(1, temps, 0);
renderingDepthBuffer = -1;
}
}
@Override
public void dispose(GL3 gl) {
maxNumSamples = 0;
destroyOffscreenBuffers(gl);
}
public int getMaxNumSamples() {
return maxNumSamples;
}
@Override
public void init(GL3 gl) {
int[] temp = new int[1];
gl.glGetIntegerv(GL.GL_MAX_SAMPLES, temp, 0);
maxNumSamples = temp[0];
}
public int renderingFbo(GL3 gl, int width, int height, int desiredNumSamples) {
if (maxNumSamples < 0) {
init(gl);
}
int targetNumSamples = Math.max(1, Math.min(maxNumSamples, desiredNumSamples));
long lastDisplay = this.lastDisplay;
this.lastDisplay = System.currentTimeMillis();
long elapsed = this.lastDisplay - lastDisplay;
GL3 gl3 = gl;
if (renderingFbo < 0 || renderingFboWidth < width || renderingFboHeight < height
|| targetNumSamples != currentNumSamples
|| elapsed >= 1000 && (renderingFboWidth != width || renderingFboHeight != height)) {
destroyOffscreenBuffers(gl3);
int[] temps = new int[2];
renderingFboWidth = width;
renderingFboHeight = height;
gl3.glGenFramebuffers(1, temps, 0);
renderingFbo = temps[0];
gl3.glBindFramebuffer(GL.GL_FRAMEBUFFER, renderingFbo);
gl3.glGenRenderbuffers(2, temps, 0);
renderingColorBuffer = temps[0];
renderingDepthBuffer = temps[1];
currentNumSamples = targetNumSamples;
if (currentNumSamples > 1) {
gl3.glBindRenderbuffer(GL_RENDERBUFFER, renderingColorBuffer);
gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, currentNumSamples, GL.GL_RGBA8,
renderingFboWidth, renderingFboHeight);
gl3.glBindRenderbuffer(GL_RENDERBUFFER, renderingDepthBuffer);
gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, currentNumSamples, GL_DEPTH_COMPONENT32,
renderingFboWidth, renderingFboHeight);
} else {
gl3.glBindRenderbuffer(GL_RENDERBUFFER, renderingColorBuffer);
gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_RGBA8, renderingFboWidth, renderingFboHeight);
gl3.glBindRenderbuffer(GL_RENDERBUFFER, renderingDepthBuffer);
gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32, renderingFboWidth, renderingFboHeight);
}
gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderingColorBuffer);
gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderingDepthBuffer);
}
return renderingFbo;
}
}