Reputation: 597
I am working on a GameBoy emulator and using Java2D for drawing. However my current method of drawing is causing a lot of flickering on my Linux machine. This flickering is not present on my friend's Mac.
I should explain graphics on the GameBoy a bit first. The GameBoy does not maintain an array of pixel data to be drawn, but instead has a list of sprite and tile data that is rendered. There is also a byte in memory that contains the current x coordinate of the vertical line that is being rendered.
Because I need to monitor the current x position of what is being drawn, I figured that the best way to draw everything was to loop through all the tiles and sprites, rendering them to a BufferedImage, and then go through this BufferedImage and plot it pixel by pixel while updating the spot in memory with the current x coordinate.
Here is my code:
@Override
public void paint(Graphics graphics) {
super.paint(graphics);
Graphics2D g = (Graphics2D) graphics;
BufferedImage secondBuffer = new BufferedImage(160, 144, BufferedImage.TYPE_INT_RGB);
Graphics2D bg = secondBuffer.createGraphics();
display.draw(ram, buffer.createGraphics());
for (int y = 0; y < 144; y++) {
for (int x = 0; x < 160; x++) {
bg.setPaint(new Color(buffer.getRGB(x, y)));
bg.drawLine(x, y, x, y);
ram.getMemory().put(Ram.LY, (byte) x);
}
}
bg.dispose();
g.drawImage(secondBuffer, null, 0, 0);
cpu.setInterrupt(Cpu.VBLANK);
}
I am not an expert with Java2D, so there could be something going on under the hood that I am not familiar with. I cannot figure out why this is code is causing flickering.
EDIT: It may or may not be relevant that I am using OpenJDK. I have heard that it has some graphical issues, but I do not know if that is the cause.
Upvotes: 3
Views: 986
Reputation: 597
I found the issue. I made the foolish mistake of mixing AWT and Swing, since I do not do GUIs or Java very much. I was drawing on a Canvas, not a Swing object. When I switched to a Swing object (the rest of my GUI is Swing), the flickering went away.
Upvotes: 0
Reputation: 2812
When I experience weird graphics issues with swing it's almost always because I am manipulating data objects at the same time swing is trying to render them. The easiest way to get around this concurrency issue is by using SwingUtilities.invokeLater(). The example code below will be invoked inside the swing thread and not your application's main thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
CHANGE DATA STRUCTURES HERE
}});
Due to how OS dependent thread behavior is these problems manifest themselves different on each computer. For more information see:
http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
Upvotes: 1