Java-Gaming.org
Play Revenge of the Titans! The situation is critical. We need fancy commanders to defend Earth, the moon, Mars!
Featured games (78)
games approved by the League of Dukes
Games in Showcase (408)
games submitted by our members
Games in WIP (293)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  What might make Graphics2D.drawImage() slow?  (Read 2995 times)
0 Members and 1 Guest are viewing this topic.
Offline Jacob_

Junior Member


Projects: 3



« Posted 2011-02-25 00:05:55 »

I'm developing a physics sandbox game. I can easily fill the whole screen with rotated, scaled, textured boxes without noticing any FPS drops or excessive CPU usage, and drawing the character without a rotate transformation is fast.

However, if I rotate the character image, or scale it, CPU usage goes through the roof and there is a small but noticable FPS decrease. Using a profiler, I determined that drawImage() was the problem. As far as I can tell the character and texture images are being drawn the same way... It's really confounding.

From the character:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
private VolatileImage character = Util.getGraphicsConfiguration().createCompatibleVolatileImage(200, 200, Transparency.BITMASK); //I tried using Transparency.TRANSLUCENT
[...]
    public void draw(Graphics g) throws BuildismException
    {
        updateImage(); //This line draws the appropriate sections of the player's skin in the right locations. If I remove it, the character is a white box, but drawing it is still slow!
       Vec2D pos = getPart().getPosition().worldToScreen(Main.getView());
        int w = (int) (200*(Main.getView().scaleFactor/8));
        int h = (int) (200*(Main.getView().scaleFactor/8));
        int imgX = (int) pos.getX() - w/2;
        int imgY = (int) pos.getY() - h/2;
        AffineTransform orig = ((Graphics2D)g).getTransform();
        AffineTransform rotate = AffineTransform.getRotateInstance(-Math.toRadians(getPart().getRotation()), pos.getX(), pos.getY());
        ((Graphics2D)g).setTransform(rotate);
        g.drawImage(character, imgX, imgY, w, h, null); //I tried using a scale transform here, didn't help
       ((Graphics2D)g).setTransform(orig);
    }


For textured boxes (yes, I know this code is messy and unoptimized... but it works faster than the much simpler code for drawing a character!)
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
    public void setTexture(BufferedImage t)
    {
        if(t != null)
        {
            VolatileImage i = Util.getGraphicsConfiguration().createCompatibleVolatileImage(t.getWidth(), t.getHeight(), Transparency.TRANSLUCENT);
            Graphics2D g2 = (Graphics2D) i.getGraphics();
            Composite old = g2.getComposite();
            g2.setColor(transparent);
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT));
            g2.fillRect(0, 0, t.getWidth(), t.getHeight());
            g2.setComposite(old);
            g2.drawImage(t, 0, 0, null);
            texture = i;
        }
        else
            texture = null;
    }

[...]

            Graphics2D g2 = (Graphics2D) g;
            Vec2D worldPos = new Vec2D(body.getPosition());
            Vec2D imgPos = worldPos.add(new Vec2D(-getVec2DProp("Size").getX(), getVec2DProp("Size").getY()).mul(0.5)).worldToScreen(Main.getView());
            Vec2D rotateCenter = worldPos.worldToScreen(Main.getView());
            AffineTransform original = g2.getTransform();
            AffineTransform scale = AffineTransform.getScaleInstance(scaleDimensionForScreen(texture.getWidth(), getVec2DProp("Size").getX()), scaleDimensionForScreen(texture.getHeight(), getVec2DProp("Size").getY()));
            AffineTransform rotate = AffineTransform.getRotateInstance(-body.getAngle(), rotateCenter.getX(), rotateCenter.getY());
            g2.setTransform(rotate);
            g2.transform(scale);
            g2.drawImage(texture, (int) (imgPos.getX() / ((Main.getView().scaleFactor * getVec2DProp("Size").getX())/texture.getWidth())), (int) (imgPos.getY() / ((Main.getView().scaleFactor * getVec2DProp("Size").getY())/texture.getHeight())), null); //ew
           g2.setTransform(original);


Does anyone see a problem?
Offline refri89

Senior Newbie





« Reply #1 - Posted 2011-02-26 21:57:28 »

-do you use new() operator inside paintComponent(Graphics g), if so try to avoid this use preallocation wherever possible
-if you use composites this slows down too
-a VolatileImgage can get lost and should be checked for validity inside drawing, like here:
http://download.oracle.com/javase/6/docs/api/java/awt/image/VolatileImage.html
-instead of VolatileImage it is often recommended to use BufferStrategy:
http://download.oracle.com/javase/6/docs/api/java/awt/image/BufferStrategy.html
http://gpwiki.org/index.php/Java:Tutorials:Double_Buffering
Offline zammbi

JGO Coder


Medals: 4



« Reply #2 - Posted 2011-02-26 22:53:48 »

Java scaling will be slow if you have the scaling on high quality. There is also a hardware scaling flag you can use.

Current project - Rename and Sort
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

Play Revenge of the Titans! The situation is critical. We need fancy commanders to defend Earth, the moon, Mars!
 
Try the Free Demo of Revenge of the Titans

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

The invasion has landed! On Mars! And you're there to beat 'em!
cubemaster21 (143 views)
2013-05-17 21:29:12

alaslipknot (151 views)
2013-05-16 21:24:48

gouessej (182 views)
2013-05-16 00:53:38

gouessej (175 views)
2013-05-16 00:17:58

theagentd (186 views)
2013-05-15 15:01:13

theagentd (171 views)
2013-05-15 15:00:54

StreetDoggy (214 views)
2013-05-14 15:56:26

kutucuk (239 views)
2013-05-12 17:10:36

kutucuk (237 views)
2013-05-12 15:36:09

UnluckyDevil (243 views)
2013-05-12 05:09:57
Complex number cookbook
by Roquen
2013-04-24 12:47:31

2D Dynamic Lighting
by Oskuro
2013-04-17 16:46:12

2D Dynamic Lighting
by Oskuro
2013-04-17 16:45:57

2D Dynamic Lighting
by Oskuro
2013-04-17 16:23:20

Noise (bandpassed white)
by Roquen
2013-04-05 17:36:01

Noise (bandpassed white)
by Roquen
2013-04-03 16:17:38

Java Data structures
by Roquen
2013-03-29 13:21:12

Topic Request
by kutucuk
2013-03-22 21:42:01
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!
Page created in 0.204 seconds with 20 queries.