First thanks to all for your help!
Can anybody provide a short example which uses FBO instead of PBuffer?
I have used the following code (which at least works, but I doubt in the strict correctness of what I did).
Please let me know your comments and remarks. What about opengl context and make current? Is it okay to use PBuffer the way I did?
If PBuffer is the current drawable, it seems, that reshape(…) of GLEventListener is never called. That’s why I had to setup matrizes in display(…) …
Perform screenshot
// called from within AWT thread
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) {
System.out.println("Requires pbuffer support for screen shot");
} else {
GLCapabilities glcaps = new GLCapabilities();
glcaps.setDoubleBuffered(false);
int width = 1000;
int height = 1000;
GLPbuffer pBuffer = GLDrawableFactory.getFactory().createGLPbuffer(glcaps, null, width, height, null);
scene.registerScreenshotDrawable( pBuffer );
pBuffer.addGLEventListener( scene );
pBuffer.display();
BufferedImage bi = scene.getScreenshotImage();
File file = new File("test.png");
try {
if (!ImageIO.write( bi, FileUtil.getFileSuffix(file), file)) {
System.err.println("Error writing file using ImageIO (unsupported file format?)");
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
The Scene class implements GLEventListener.
public class Scene
extends Object
implements GLEventListener, MouseListener, MouseMotionListener, MouseWheelListener
{
[....]
protected GLAutoDrawable screenshotDrawable;
protected BufferedImage screenShotImage;
public void registerScreenshotDrawable(GLAutoDrawable pBuffer) {
screenshotDrawable = pBuffer;
}
public BufferedImage getScreenshotImage() {
return screenShotImage;
}
public void init(GLAutoDrawable drawable) {
// setup lightning
// enable opengl features
}
public void display(GLAutoDrawable drawable) {
consumeAllMouseEvents();
gl = drawable.getGL();
if (drawable == screenshotDrawable) {
float ratio = (float)1000 / (float)1000;
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustum(-1.0f, 1.0f, -ratio, ratio, 5.0f, 1000.0f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
if (mode == GL.GL_RENDER) {
if ((drawable instanceof GLJPanel) &&
!((GLJPanel) drawable).isOpaque() &&
((GLJPanel) drawable).shouldPreserveColorBufferIfTranslucent()) {
gl.glClear(GL.GL_DEPTH_BUFFER_BIT);
} else {
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
}
gl.glPushMatrix();
gl.glLoadMatrixd( orbitRotation.getCameraMatrix(), 0 );
renderObjects();
gl.glPopMatrix();
}
if (drawable == screenshotDrawable) {
System.out.println("This is screenshot");
screenShotImage = Screenshot.readToBufferedImage(1000, 1000, false);
}
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
gl = drawable.getGL();
ratio = (float)height / (float)width;
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustum(-1.0f, 1.0f, -ratio, ratio, 5.0f, 1000.0f);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
// not implemented
}
}
Will also try to use TileRenderer for bigger resolution images.