Reputation: 99
I'd like to program a 2D game engine. The problem i have (i don#t use opengl and stuff like that, so i render with cpu) is, that i only get 7fps through the graphics.drawImage(); Do you have any suggestions to speed this up or any alternatives?
image = new BufferedImage(gc.getWidth(), gc.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
canvas.createBufferStrategy(1);
bs = canvas.getBufferStrategy();
g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, canvas.getWidth(), canvas.getHeight(), null);
My renderer should simply color the frame (width 320 height 240 pixels) cyan, and he does, but only at a maximum of 8fps. Renderer:
private int width, height;
private byte[] pixels;
public Renderer(GameContainer gc){
width = gc.getWidth();
height = gc.getHeight();
pixels = ((DataBufferByte)gc.getWindow().getImage().getRaster().getDataBuffer()).getData();
}
public void clear(){
for(int x = 0; x < width; x++){
for(int y = 0; y < height; y++){
int index = (x + y * width) * 4;
pixels[index] = (byte)255;
pixels[index+1] = (byte)255;
pixels[index+2] = (byte)255;
pixels[index+3] = 0;
}
}
}
Upvotes: 0
Views: 1855
Reputation: 23
I know i'm a little late to this party but for anyone looking at this in the future:
Dont try to handle your images as arrays!
If you want to color your whole screen or an Image using a canvas, get the Graphics object as described above and use a rectangle to fill your screen like this:
g.setColor(new Color(REDVALUE,GREENVALUE,BLUEVALUE);
g.fillRect(0,0,canvas.getWidth(),canvas.getHeight());
If your current class extends Canvas then you can obviously use:
getWidth() and getHeight()
Instead of:
canvas.getWidth() and canvas.getHeight()
If you have problems understanding how the Graphics object works you might want to take a look at this first.
If you want to do more complex Image manipulation this might help you.
EDIT: Drawing big images is somehow (???) slower then drawing small images to fill the same area.
Upvotes: 1
Reputation: 1720
I'm not really sure how to optimize your current example (but does using the data buffer in clear
really create a speedup from just using Graphics.fillRect
?), but I can give you some general Java2D tips.
First of all, using the most compatible image type for your computer is important. Here is a method to find a compatible image:
private static final GraphicsConfiguration GFX_CONFIG = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
public static BufferedImage toCompatibleImage(final BufferedImage image) {
/*
* if image is already compatible and optimized for current system settings, simply return it
*/
if (image.getColorModel().equals(GFX_CONFIG.getColorModel())) {
return image;
}
// image is not optimized, so create a new image that is
final BufferedImage new_image = GFX_CONFIG.createCompatibleImage(image.getWidth(), image.getHeight(), image.getTransparency());
// get the graphics context of the new image to draw the old image on
final Graphics2D g2d = (Graphics2D) new_image.getGraphics();
// actually draw the image and dispose of context no longer needed
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
// return the new optimized image
return new_image;
}
It is also generally good practice to dispose of Graphics objects when you're done with them (it might help if you create them in a tight loop).
Here are some other questions that give some tips:
Java 2D Drawing Optimal Performance
Upvotes: 1