0

I'm working on a simple 2D game, rendering via the Java2D API. I've noticed that when I try to draw on integrated graphics card the performance crashes.

I've tested this game on both my main rig with a newer ATI Radeon and my 5 year old laptop which also has an (incredibly antiquated) Radeon. On both I get good FPS, but when I try to use my Intel i5's onboard HD 4000 graphics, it crawls at around 20 FPS.

I'm using Full Screen Exclusive mode.

At any given moment, I am rendering approximately 1000 images at once.

Annoyingly, when I try to getAvailableAcceleratedMemory() it just returns -1 for this card, and it seems to refuse to accelerate any images.

Does anyone have any ideas how to fix this issue?

Rendering code:

    Graphics g = bufferStrategy.getDrawGraphics();
    g.drawImage(img, x, y, img.getWidth(), img.getHeight(), null)
    g.dispose();
    bufferStrategy.show();

Image Loading code:

    BufferedImage I = null;
    I = ImageIO.read(new File(currentFolder+imgPath));
    imgMap.put(imgIdentifier, I);

The images are stored in a hashmap of BufferedImages identified by strings, so when an entity needs to draw and image it just gets it out of the hashmap and draws it. In the current case, the entities are mostly floor and wall tiles, so they never change (and thus don't have to get the image from the hashmap other than the very first time).

EDIT - I've incorporated MadProgrammer's method, but it didn't change my FPS.

  • 1
    You could try using [`GraphicsConfiguration#createCompatiableImage`](http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsConfiguration.html#createCompatibleImage(int,%20int,%20int)) and draw the images you've loaded to them. This will save the time in converting the images on the fly each time... – MadProgrammer Oct 21 '13 at 04:51
  • I've seen a few posts about that, and I've fiddled about with it a bit and it only drew like 3 of my images and the rest of the time drew nothing. I assume I did something wrong. Could you elaborate on whereabouts in the snippets I've provided I'd do that? –  Oct 21 '13 at 04:54
  • 1
    I've added the code that I use. Hope it helps...I used this to produce a multi layered, transparent animation of multiple images and it made a massive difference on my Mac laptop – MadProgrammer Oct 21 '13 at 04:57
  • Thanks! I just tried it out (sans the g2d.drawimage stuff), but it didn't really help. It did render correctly, but it didn't alter my FPS. EDIT: Added in the g2d.drawImage stuff, no change. –  Oct 21 '13 at 05:10
  • What version of OS are JRE are using? Are they the same bit deepthness (32 or 64bit)? It could be an incompatibility with the driver – MadProgrammer Oct 21 '13 at 05:12
  • You try having a look at [this post](http://stackoverflow.com/questions/14635377/java-hardware-acceleration-not-working-with-intel-integrated-graphics) which might help – MadProgrammer Oct 21 '13 at 05:13
  • OS: Windows 7 Enterprise 64 Bit (6.1) Java (cmd java -version) java version "1.7.0_40" Java(TM) SE Runtime Environment (build 1.7.0_40-b43) Java HotSpot(TM) 64-Bit Server VM (build 24.0-b56, mixed mode) –  Oct 21 '13 at 05:19
  • I looked at that other post when Radio posted it below, they didn't seem to have any answers that apply to my case, but I'll run his code at least. –  Oct 21 '13 at 05:19

1 Answers1

2

This is an example of converting an image to a compatiable image...not an answer in of itself

This is some of the library code that I use...

public static BufferedImage createCompatibleImage(BufferedImage image) {
    BufferedImage target = createCompatibleImage(image, image.getWidth(), image.getHeight());
    Graphics2D g2d = target.createGraphics();
    g2d.drawImage(image, 0, 0, null);
    g2d.dispose();
    return target;
}

public static BufferedImage createCompatibleImage(BufferedImage image,
        int width, int height) {
    return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency());
}

public static GraphicsConfiguration getGraphicsConfiguration() {
    return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}

I would do something like...

I = createCompatibleImage(ImageIO.read(new File(currentFolder+imgPath)));
imgMap.put(imgIdentifier, I);
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I'm about to try this out, but what exactly is the benefit of the lines where you create a Graphics2D object and draw it? Or do you use this slightly differently in your code? –  Oct 21 '13 at 05:03
  • I am pretty sure I have read that hardware acceleration is finicky on integrated graphics. Either way, I've have noticed improvements on an HD 3000 with createCompatibleImage and you should be doing it anyway. Maybe see also: http://stackoverflow.com/questions/14635377/java-hardware-acceleration-not-working-with-intel-integrated-graphics – Radiodef Oct 21 '13 at 05:03
  • @BattleBarnes You create an image that is (hopefully) of a more compatible format with the display device and draw the images that you load from a file on to it. Then do whatever you are going to do with the image using the compatible image instead of the one from the file. – Radiodef Oct 21 '13 at 05:05
  • The way I'm understanding this, the g2d and g2d.drawImage aren't what make it more capable. I think the operative code is the createCompatibleImage stuff, is it not? –  Oct 21 '13 at 05:08
  • @BattleBarnes Basically what the code is trying to is generate an image whose data structure and color model are compatible with the underlying `GraphicsConfiguration` so that when it is painted, it does not need to convert the image on the fly, every time. Basically, the act of painting the original image onto the "compatible" image does the conversation for us, once. – MadProgrammer Oct 21 '13 at 05:10