I have seen a lot of blogs with code in the last week so I wanted to share something of my own with the 64Digits world. this little snip-it contains a magic image buffer that turns standard color images to indexed CRT graphics.
Just chilling inside a house model I created in blender.
public class OldSchoolBuffer {
private static final int[] INDEX = new int[] {
0x000000, 0x7F7F7F, 0xC0C0C0, 0xFFFFFF,
0x7F0000, 0xFF0000, 0x7F7F00, 0xFFFF00,
0x007F00, 0x00FF00, 0x007F7F, 0x00FFFF,
0x00007F, 0x0000FF, 0x7F007F, 0xFF00FF
};
private BufferedImage imageCRT;
private BufferedImage image16B;
private int rate;
private int scanline;
public OldSchoolBuffer(int width, int height, int rate) {
this.imageCRT = new BufferedImage(width, height,
BufferedImage.TYPE_INT_BGR);
byte[] reds = new byte[INDEX.length];
byte[] greens = new byte[INDEX.length];
byte[] blues = new byte[INDEX.length];
for(int i = 0; i < INDEX.length; i++) {
reds[i] = (byte) ((INDEX[i] >> 16) & 0xFF);
greens[i] = (byte) ((INDEX[i] >> 8) & 0xFF);
blues[i] = (byte) ((INDEX[i] >> 0) & 0xFF);
}
IndexColorModel colorModel = new IndexColorModel(3, 16, reds,
greens, blues);
this.image16B = new BufferedImage(width / 4, height / 4,
BufferedImage.TYPE_BYTE_INDEXED, colorModel);
this.rate = rate * height;
this.scanline = 0;
}
public void update() {
Graphics2D graphics = (Graphics2D) imageCRT.getGraphics();
graphics.drawImage(image16B, 0, 0, imageCRT.getWidth(), imageCRT.getHeight(), null);
graphics.dispose();
}
public void update(float elapse) {
int lineStep = (int) (rate * elapse);
scanline = (scanline + lineStep) % imageCRT.getHeight();
for(int y = 0; y < imageCRT.getHeight(); y++) {
for(int x = 0; x < imageCRT.getWidth(); x++) {
int index = image16B.getRGB(x / 4, y / 4);
if((x + 1) % 4 == 0) {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.50f), (int) (getGreen(index) * 0.25f), (int) (getBlue(index) * 0.50f)));
} else if((y + 1) % 4 == 0) {
if((x + 1) % 3 == 0) {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.125f), (int) (getGreen(index) * 0.25f), (int) (getBlue(index) * 0.50f)));
} else if((x + 1) % 2 == 0) {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.25f), (int) (getGreen(index) * 0.50f), (int)(getBlue(index) * 0.25f)));
} else {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.50f), (int) (getGreen(index) * 0.25f), (int)(getBlue(index) * 0.125f)));
}
} else {
if((x + 1) % 3 == 0) {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.50f), (int) (getGreen(index) * 0.75f), getBlue(index)));
} else if((x + 1) % 2 == 0) {
imageCRT.setRGB(x, y, getRGB((int) (getRed(index) * 0.75f), getGreen(index), (int)(getBlue(index) * 0.75f)));
} else {
imageCRT.setRGB(x, y, getRGB(getRed(index), (int) (getGreen(index) * 0.75f), (int)(getBlue(index) * 0.50f)));
}
}
}
}
}
private int getRGB(int r, int g, int b) {
return ((r & 0xFF) << 16) |
((g & 0xFF) << 8) |
((b & 0xFF) << 0);
}
public int getRed(int rgb) {
return ((rgb >> 16) & 0xFF);
}
public int getGreen(int rgb) {
return ((rgb >> 8) & 0xFF);
}
public int getBlue(int rgb) {
return ((rgb >> 0) & 0xFF);
}
public void render(Graphics2D graphics) {
graphics.drawImage(imageCRT, 0, 0, null);
}
public Graphics2D getGraphics() {
return (Graphics2D) image16B.getGraphics();
}
}
I will only have this as an option in the final game. It kills frame rate as you can see in the image, and I shouldn't waste time optimizing it…LOL
Not gonna lie, that code confuses me a great deal :P
The bit bit before the end called everything.
The whole point of this code is to turn the rendered graphics into something resembling a crt tv.
I'm not gonna lie that's kinda painful to look at. Maybe it looks better in action, but also maybe worse.
Of all the ways to retro-fy graphics why did you go with CRT? Is it relevant to the theme or story or mood or something of your game?Just so you all know I abandoned this effect due to the loss of frame rate… I just thought it looked cool and I wanted to share…LOL
That's ironic that it takes more memory to make the graphics look like they use less memory.
I guess it's to be expected though.Ahh Java we meet again.
I think its a cool effect, but it does seem redundant in processing all of the pixels.I agree, it is kinda painful to look at. Guess I haven't looked at one of those screens in quite a while! Ha. Probably better experienced in motion, though, too.