A very simple solution would be to implement your own copyArea function that accepts a format parameter.
Code:
public void copyArea(GameContainer c, Image target, int x, int y, int format) {
target.bind();
GL11.glCopyTexImage2D(SGL.GL_TEXTURE_2D, 0, format, x, c.getHeight()
- (y + target.getHeight()), target.getTexture().getTextureWidth(),
target.getTexture().getTextureHeight(), 0);
target.ensureInverted();
}
public void init(GameContainer container) throws SlickException {
// we will use this for our "screen shot"
screenCapture = new Image(container.getWidth(), container.getHeight());
}
public void render(GameContainer container, Graphics g) throws SlickException {
// render your scene as per usual
renderScene(g);
// if we should take a screen shot on this frame, then copy the area:
if (grabScreen) {
//we don't want to do this every frame if we can help it
grabScreen = false;
copyArea(container, screenCapture, 0, 0, GL11.GL_LUMINANCE8);
}
// and then we can draw the grayscale screen shot like an image
screenCapture.draw(0, 0, 0.25f); // 25% scale
}
Using this, each colour is scaled by 1, so red, blue and green would all show up as white. Converting to a more convincing grayscale image requires scaling the values first; this
GIMP article suggests scaling 30% red, 59% green, and 11% blue; whereas
this article suggests other values. You can include this in your code to scale the colours:
Code:
GL11.glPixelTransferf(GL11.GL_RED_SCALE, 0.30f);
GL11.glPixelTransferf(GL11.GL_GREEN_SCALE, 0.59f);
GL11.glPixelTransferf(GL11.GL_BLUE_SCALE, 0.11f);
copyArea(container, screenCapture, 0, 0, GL11.GL_LUMINANCE8);
GL11.glPixelTransferf(GL11.GL_RED_SCALE, 1f);
GL11.glPixelTransferf(GL11.GL_GREEN_SCALE, 1f);
GL11.glPixelTransferf(GL11.GL_BLUE_SCALE, 1f);
Because we are scaling the colours, the image will be darker and we will want to brighten it. The best solution would be proper gamma correction, but some easier solutions would be to (a) use BIAS and glPixelTransfer to add a certain amount to the resulting color before copying to grayscale, or (b) render the screen capture in multiple passes using Slick's MODE_ADD.
Things to note: