Re: FBO with GLCanvas
Posted by Bob on Nov 27, 2019; 11:57am
URL: https://forum.jogamp.org/FBO-with-GLCanvas-tp4040147p4040148.html
Here is the full code I used to make tests:
public class TestsCanvasFBO implements GLEventListener
{
private static int fboId = -1;
private static boolean doScreenshot = false;
public static void main(String[] args)
{
SwingUtilities.invokeLater(
() ->
{
GLProfile glp = GLProfile.getDefault();
GLCapabilities caps = new GLCapabilities(glp);
GLCanvas canvas = new GLCanvas(caps);
canvas.addGLEventListener(new TestsCanvasFBO());
Button screenshotButton = new Button("Screenshot");
screenshotButton.addActionListener(e ->
{
doScreenshot = true;
canvas.display();
});
Frame frame = new Frame("FBO Test");
frame.setSize(1000, 1000);
frame.add(canvas, BorderLayout.CENTER);
frame.add(screenshotButton, BorderLayout.PAGE_END);
frame.setVisible(true);
});
}
@Override
public void init(GLAutoDrawable drawable)
{
// drawable.setGL(new DebugGL2(drawable.getGL().getGL2()));
drawable.getGL().glClearColor(0, 0, 0, 1);
initialiseFBO(drawable.getGL(), drawable.getSurfaceWidth(), drawable.getSurfaceHeight());
}
private static void initialiseFBO(GL gl, int width, int height)
{
// Framebuffer creation
// ----------------------
int[] ids = new int[1];
gl.glGenFramebuffers(1, ids, 0);
fboId = ids[0];
gl.glGenRenderbuffers(1, ids, 0);
int rbId = ids[0];
gl.glBindFramebuffer(GL_FRAMEBUFFER, fboId);
gl.glBindRenderbuffer(GL_RENDERBUFFER, rbId);
gl.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
// Texture creation
// ------------------
gl.glGenTextures(1, ids, 0);
int tId = ids[0];
gl.glBindTexture(GL_TEXTURE_2D, tId);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
// Attach texture and render buffer to FBO
// ----------------------------------------
gl.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tId, 0);
gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbId);
gl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbId);
gl.glBindTexture(GL_TEXTURE_2D, 0);
gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
@Override
public void display(GLAutoDrawable drawable)
{
GL2 gl = drawable.getGL().getGL2();
if (doScreenshot)
{
gl.glBindFramebuffer(GL_FRAMEBUFFER, fboId);
gl.glClearColor(1, 1, 1, 1);
}
else
{
gl.glClearColor(0, 0, 0, 1);
}
gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl.glColor3f(1, 0, 0);
gl.glBegin(GL2.GL_POLYGON);
{
gl.glVertex2f(0.5f, 0.5f);
gl.glVertex2f(-0.5f, 0.5f);
gl.glVertex2f(-0.5f, -0.5f);
gl.glVertex2f(0.5f, -0.5f);
gl.glVertex2f(0f, 0f);
}
gl.glEnd();
if (doScreenshot)
{
gl.glFinish();
capture(gl);
gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
doScreenshot = false;
}
}
private static void capture(GL gl)
{
// Create image
BufferedImage bi = new AWTGLReadBufferUtil(gl.getGLProfile(), false).readPixelsToBufferedImage(gl, true);
try
{
ImageIO.write(bi, "PNG", new File("./capture.png"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h)
{
}
@Override
public void dispose(GLAutoDrawable drawable)
{
deleteFBO(drawable);
}
private void deleteFBO(GLAutoDrawable drawable)
{
GL gl = drawable.getGL();
// Dispose resources
int[] ids = new int[1];
// Texture
gl.glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ids, 0);
gl.glDeleteTextures(1, ids, 0);
// Render buffer
gl.glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ids, 0);
gl.glBindRenderbuffer(GL_RENDERBUFFER, 0);
gl.glDeleteRenderbuffers(1, ids, 0);
// Frame buffer
gl.glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, ids, 0);
gl.glBindFramebuffer(GL_FRAMEBUFFER, 0);
gl.glDeleteFramebuffers(1, ids, 0);
}
}