Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (513)
Games in Android Showcase (120)
games submitted by our members
Games in WIP (577)
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 4117 times)
0 Members and 1 Guest are viewing this topic.
Offline Jacob_

Junior Duke


Projects: 3



« Posted 2011-02-24 23: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 20: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 21: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.

 

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

The first screenshot will be displayed as a thumbnail.

Longarmx (52 views)
2014-10-17 03:59:02

Norakomi (44 views)
2014-10-16 15:22:06

Norakomi (33 views)
2014-10-16 15:20:20

lcass (38 views)
2014-10-15 16:18:58

TehJavaDev (68 views)
2014-10-14 00:39:48

TehJavaDev (68 views)
2014-10-14 00:35:47

TehJavaDev (60 views)
2014-10-14 00:32:37

BurntPizza (73 views)
2014-10-11 23:24:42

BurntPizza (45 views)
2014-10-11 23:10:45

BurntPizza (86 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
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!