Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 7 of 7

Thread: Increasing performance of my graphics routines

  1. #1
    Junior Member
    Join Date
    Nov 2009
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Increasing performance of my graphics routines

    Hi there,

    I'm currently working on a smallish tile-based game with my friend, just a little summer project. We're both pretty square in the middle of 'intermediate' level coders, I would guess.

    Our game has some fairly meaty algorithms happening, and so we're very cpu-cycle concious. However, as it happens, our algorithms aren't really wasting too much time (yay!), the current greatest offender is...



    ... drawing graphics!

    It's not maxing out a CPU yet, and it's not something that has the chance to balloon as the program grows - as it will only ever be rendering the same number of tiles. It also is responsive enough in-game, so we're not worried, per se, but we'd like to get the time spent there down so we have more room for everything else.

    We're clearly not entirely solid on how best to do things in Java, so some help would be greatly appreciated.

    The way it's currently implemented, is:
    • Everything is eventually drawn to an object which subclasses JPanel, its paintComponent(Graphics g) is overridden, and it also implements Runnable. The run method has a loop which ensures that the object is repaint()'ed regularly.
          ....
              public void paintComponent(Graphics g){
                  super.paintComponent(g); 
       
                  Graphics2D g2d = (Graphics2D) g;
                  Dimension size = getSize();
       
                  // If we're in a game, draw the game
                  if(worlds[currentWorld].currentGame != null){
                      worlds[currentWorld].currentGame.draw(g2d, size);
                  }
       
              }
          ....
    • As you can see, we're not drawing straight to the screen. A Graphics2D object is created, and then passed down into the bowels of the game object hierarchy. The Graphics2D object is passed down through many objects' draw() functions until it gets all the way down to a Sprite. Here, the actual g.drawImage(...) is called. This is the function that takes all the time:
          public void draw(Graphics2D g, int x, int y){
              // Convert x and y from number of tiles to pixels
              x *= width;
              y *= height;
              g.drawImage(image, x, y, null);
          }
      Where image is an Image member variable of whichever Sprite is being drawn, and width and height are some power of 2 indicating the size of tiles.


    This may seem like some kind of weird hodgepodge of terrible, if so - it is because I have read many tutorials on the subject of drawing in java, all of which are no newer than 2005 and all of which seem to do things a different way. Also, I am just now revisiting the graphics methods after several months where I have been busy, so things have become stale in my mind.

    If anyone has any tips or would like to point out some glaring flaws, feel free to do so - it would be greatly appreciated.


  2. #2
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Increasing performance of my graphics routines

    I believe the Graphics2D class uses the CPU for drawing rather than having GPU acceleration by default. There's a setting you must pass to the JDK in order to enable OpenGL for hardware acceleration. See this website for all the details:

    2D graphics - new features

    edit: Err, I meant JRE, not the JDK.
    Last edited by helloworld922; November 15th, 2009 at 02:18 PM.

  3. #3
    Super Moderator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,234
    Thanks
    176
    Thanked 817 Times in 760 Posts
    Blog Entries
    5

    Default Re: Increasing performance of my graphics routines

    A few suggestions:
    a) Enable hardware acceleration as helloworld described
    b) use animated GIF's if you have short animations, rather than creating an animation thread
    c) Only draw things that need to be updated. You can do this several ways, one way would be to keep several flags to indicate whether drawing is necessary and evaluate those flags in the drawing hierarchy, another of which would be to use several overlayed JPanels (setOpaque to false) rather than a single JPanel to do the drawing, with each JPanel drawing things that update at different times. This way you can optimize by only drawing things that need updating.
    Last edited by copeg; November 15th, 2009 at 11:20 AM.

  4. #4
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Increasing performance of my graphics routines

    Have a look through your paint method and all the methods it calls to see if there are any calls to "new" which you could do without.

    // Json

  5. #5
    Junior Member
    Join Date
    Nov 2009
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Increasing performance of my graphics routines

    Hi guys, thanks for the replies!

    I had a look at that 2DGraphics - New Features links, and tried simply using
    -Dsun.java2d.opengl=True
    to enable OpenGL on the VM, but that just caused each frame to take 5+ seconds to render.

    So I went down the miserable rabbit hole of trying to use VolatileImages again, and just like when I did this 3 or 4 months ago, I've spent 5 hours reading tutorials and pasting code and nothing I've done has had anything but a negative effect.

    Cokencode has a nice tutorial from 2005, which is similar to how I've done things, so doesn't help me. There's a page on the gpwiki which looked useful, but I couldn't decipher how to actually have an accelerated image in a sprite class, and draw that to an accelerated buffer, and then draw that to the screen.

    The stuff made by the nice people at Sun is all very academic and thorough, but a little abstract - I learn (slowly, it seems) by doing!

    copeg: They are all good suggestions, thank you. Yes, any small/static animations are already in that format, and I'm saving your suggestion c) for when I've got a proper accelerated pipeline working.

    Json: I've been very careful with my memory allocation, there are no calls to new inside the draw() functions at all. Each image is only loaded once, and a reference to this shared amongst tiles with the same image, etc.etc.

    If anyone knows of a nice, straight-forward guide on how to get this working, I'd very much appreciate it!

  6. #6
    Super Moderator Json's Avatar
    Join Date
    Jul 2009
    Location
    Warrington, United Kingdom
    Posts
    1,274
    My Mood
    Happy
    Thanks
    70
    Thanked 156 Times in 152 Posts

    Default Re: Increasing performance of my graphics routines

    You have to realise though that the time spent on graphics will always be high, well the higher the better really, because that means you can squeeze out more FPS and your game updates take less time.

    How many FPS do you get at the moment?

    // Json

  7. #7
    Junior Member
    Join Date
    Nov 2009
    Posts
    5
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Re: Increasing performance of my graphics routines

    Currently the CPU isn't saturated, so I'm getting a solid 60 FPS. However, the issue is that any graphics done by the CPU is now vying for the same resources as the rest of the game, and even though the graphics requirements are not going to grow (tiles is tiles is tiles, and I'm rendering as many as I'll ever render), the game logic requirements will grow.

    So yes, I do intend on getting this working. I'm sure the high amount of time the game is spending in that draw method is just sending the tile data across the bus so many times, and I know that getting it properly working all on the graphics card memory will result in an increase... it just hasn't yet! Very frustrated, but not defeated!

Similar Threads

  1. Performance of Type Casting and Conversions
    By fritzoid in forum Java Theory & Questions
    Replies: 1
    Last Post: October 1st, 2009, 07:56 PM
  2. Simple graphics practice on previous Java code
    By amrawad_85 in forum AWT / Java Swing
    Replies: 5
    Last Post: June 19th, 2009, 10:30 AM
  3. Cracking password in less number of Trials using brute forcea
    By xisstar in forum What's Wrong With My Code?
    Replies: 2
    Last Post: June 10th, 2009, 10:40 AM
  4. Replies: 1
    Last Post: May 13th, 2008, 08:08 AM