Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (487)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
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  
  Java2D clearing up the Air  (Read 1824 times)
0 Members and 1 Guest are viewing this topic.
Offline StumpyStrust
« Posted 2012-10-10 01:41:22 »

Here is the tutorial/article I am working on. Any other tips/corrections would be great. Basically, tips/tricks/corrections about java2D

After reading all the posts that constantly ask the fastest way to render/draw stuff in jave2D or best way of drawing in java2D and all sorts of speed/trick/hint questions, I decided to write a quick tut about java2D. I am going to give you a bunch of info about java2D that should give you a good understanding what to expect when using java2D and how to do a bunch of stuff. First made sure you know how to setup an app that uses double buffering before you read this. There are plenty of links on this site so just do a search first.

Java2D is not meant for game development and thus is much slower than anything that uses opengl.
(hint: slick, libgdx, lwjgl <--not a game lib)
If you want to make simple games, than it is more than enough but do not expect to make an AAA title with it.


First: Best way to draw/render image in java2D


Simple.

1  
g.drawImage(...)


That is probably the easiest and fastest way to get pixels onto the screen. There are all sorts of other ways but this is ridiculously easy and is fast.

Second: Scaling/fillrate

Fillrate, put simply, is how many pixels your graphics card can pump out every frame. In most opengl 2d engines this is your biggest bottle neck. In java2D however, it is not. You can do a whole lot of pixel filling before you see performance drops often you will hit the real bottle neck of java2D first, which is listed below.

So what is the easiest/most efficient way of scaling an image in java2D?

1  
g.drawImage(... width, height)


Yup you can just add in the width and height you want the image to be and grab a can of soda/beer (or bottle if that is your thing) because I have never seen any performance drop in scaling images smaller or larger and if there is one, it is tiny.


Third: Transparency/Alpha blending performance hit

Easiest way of doing alpha blending is this

1  
2  
3  
 
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float) (yourAlpha)));
g2d.drawImage(...);


The performance hit for blending is very small. It exists but you will not see a huge difference and alpha transparency is kinda a must for games.

Note: java does not do additive blending. Also, please read below about BufferedImages and VolatileImages with alpha blending.


Fourth: Volatile or Buffered?


All images you create in java2D are hardware accelerated by default since java 1.5. So any ImageIcons or what ever will be fast. There are no special tricks to get a "managed" image as they are managed already. BufferedImages are not to be used as a back buffer or drawing surface. Basically, do not grab a BufferedImage's graphics object and draw with it as it will be very slow. Some say that you need to create compatible images when using BufferedImages but I have never had an issue and I will post some code at the end that abstracts this away from you.

VolatileImages are much faster then BufferedImages when the image has no transparency. When you turn on blending their performance is cut in half. Buffer Strategies use a VolatileImage as a back buffer so these are ideal for drawing surfaces. You can use getSnapShot() to get a BufferedImage from a VolatileImage if you want to do tricks on the pixels.

VolatileImages are hard to manage and are not as versatile as BufferedImages so stick to buffs.

Fifth: Performance Tips/Bottle Neck: ........

The biggest bottle neck you will encounter is draw calls. That is how often you call g2d.drawImage()/g2d.fillRect()...... You can get about 4-5k calls till most cpus will start slowing down. Anytime you can trade off fewer drawcalls for bigger images to be rendered, do it. Example would be particle systems. Keep effects using as few particles as you can. Do not worry about large images.

RenderingHints does very little to performance. The only thing you may want to turn off/on is interpolation/rendering they both do almost the same thing, whether or not to use nearest neighbor filtering or bilinear filtering. Rendering quality uses bilinear and speed uses nearest neighbor. You can turn on bicubic but that will greatly slow things down. Anti aliasing is primarily for text so no need to turn that off. Fractional metrics is also for text and keep this on as well. Dithering, color rendering, and alpha interp have not visual or performance impacts that I have seen.

The magic opengl flag. This is all experience and may not be the same for everyone so take it with a grain of salt. This flag should not be turned on unless the game is very very slow and should never be turned on when using volatile images as in every test case I have done, strange things happen.  When opengl flag is on volatile images performance drops to a snail speed and BufferedImages get a nice speed boost especially with alpha blending on. This flag can also solve problems with integrated chips be seemingly fillrate limited but I have had a great deal of weird issues with the flag on so only use it as a last resort.

Now I want to leave you with some nice utilities I use to load/manage bufferedimages. If there are other questions/additions just comment and I will add/address them.

http://pastebin.java-gaming.org/f1303887e2e

Here is also a particle toy I made in java2D that you can have fun with to test out performance.

http://www.mediafire.com/?rhhbadiv1f17cii


Offline Varkas
« Reply #1 - Posted 2012-10-10 13:37:43 »

BufferedImages are not to be used as a back buffer or drawing surface. Basically, do not grab a BufferedImage's graphics object and draw with it as it will be very slow.

Interesting. I didn't know that and it might explain some performance differences I had seen, which seemed just weird to me before. Thanks for the hint Smiley

if (error) throw new Brick(); // Blog (german): http://gedankenweber.wordpress.com
Online SHC
« Reply #2 - Posted 2013-04-16 05:44:01 »

Here's my version of the same class. ImageTool.java

http://pastebin.java-gaming.org/5c458943c58

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.

TehJavaDev (17 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (67 views)
2014-08-11 02:49:23

BurntPizza (45 views)
2014-08-09 21:09:32

BurntPizza (36 views)
2014-08-08 02:01:56
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!