Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (108)
games submitted by our members
Games in WIP (536)
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  
  transparent png and Graphics.drawImage method  (Read 4177 times)
0 Members and 1 Guest are viewing this topic.
Offline luisoft

JGO Coder


Projects: 6


Java games rock!


« Posted 2006-11-16 11:48:26 »

Hi,

I have a transparent PNG (640x320) file holding all tiles used in my game (each tile is 32x32 and has an id based on the position in the big PNG file.

I load this image into a Image object and then use the following method to draw individual tiles:

public abstract boolean drawImage(Image img, int dx1, int dy1,int dx2,int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer).

But the speed is very low, the frame rate makes it impossible to play. When I change to use the following drawImage variation:

public abstract boolean drawImage(Image img, int dx1, int dy1,int dx2,int dy2, int sx1, int sy1, int sx2, int sy2, Color color, ImageObserver observer).

The speed keeps very good (60 FPS). The problem is that the above drawImage will fill transparent portions of the image with color passed as an argument and I do not want that behaviour because I'm using another image as a background (parallax scrolling).

Do you guys know why there is this diference in speed of these two methods? And do you have a solution to keep the transparency?

Thanks a lot,
L. F. Estivalet
Offline Kova

Senior Member





« Reply #1 - Posted 2006-11-16 11:57:54 »

Load your image and  then create individual BufferedImage for every sub image from that image. That way it will get accelerated. When you have a big image it isn't accelerated I guess (but far from sure).
Offline luisoft

JGO Coder


Projects: 6


Java games rock!


« Reply #2 - Posted 2006-11-16 13:46:26 »

I think that creating multiple BufferedImages (one for each single tile) will consume too much memory instead of having just one big image holding all tiles, am I correct? I can have hundreds of tiles and I'm not sure about the performance also.

Let me know your thoughts about that.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Kova

Senior Member





« Reply #3 - Posted 2006-11-16 13:58:50 »

have you tried? I don't think it will matter, don't know how much memory is used just for BufferedImage object (without data) but my guess is that it will be irrelevant. See how much your game uses memory now, do the conversion and compare it. Note that I don't know much about it, just that big images aren't accelerated Smiley
Offline whome

Junior Member




Carte Noir Java


« Reply #4 - Posted 2006-11-16 15:23:47 »

So, if I understood you have a big alphablended tiling image. Each tile has pixels having 0-100% alpha transparency...

My guess: Without drawing a fill color might realize problems in non-hardware accelerated transparency (aka transluency). Fill color might produce some sidestep drawing algoritm thus does not suffer.

I think there are some "-Ddomagic=xxx" attribute to control transparency issues. But finding a good list of all available Java2D commandline arguments is a nightmare. I dont have a such list.
Offline luisoft

JGO Coder


Projects: 6


Java games rock!


« Reply #5 - Posted 2006-11-16 17:45:28 »

So do you guys use an array of BufferedImage to develop your tile based games?

And what about multiple layers (for parallax scrolling for example)? If you have say a game that is 640x480 and each tile is 32x32 than you will have the following structure:

BufferedImage[][] map = new BufferedImage[20][15]
BufferedImage[][] layer1 = new BufferedImage[20][15]
BufferedImage[][] layer2 = new BufferedImage[20][15]
BufferedImage[][] layer3 = new BufferedImage[20][15]

The example above we have a "map" that is where the main tiles are (where the player interacts) and layers 1, 2 and 3 are used just for background animations.

Is this the best or fast way of implementing parallax? I used to use large bitmaps and drawing only parts of it instead of having individual BufferedImages.
Offline campbell

Junior Member




Java games rock!


« Reply #6 - Posted 2006-11-16 20:16:09 »

But finding a good list of all available Java2D commandline arguments is a nightmare. I dont have a such list.

Umm, you mean like this one?
http://java.sun.com/javase/6/docs/technotes/guides/2d/flags.html

Chris
Offline luisoft

JGO Coder


Projects: 6


Java games rock!


« Reply #7 - Posted 2006-11-16 20:23:20 »

I'd really like to have a solution without using those "magic" attributes... So do you use the arrays like I mentioned in my previous post?
Offline Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #8 - Posted 2006-11-16 21:43:36 »

I'd really like to have a solution without using those "magic" attributes... So do you use the arrays like I mentioned in my previous post?

We've already had a thread cover this area.

The fastest painting method is :-
1) To have your tiles stored in a single image to avoid excessive context switching in the graphics pipeline
2) Use Graphics.drawImage(Image img, int dx1,int dy1,int dx2,int dy2,int sx1,int sy1,int sx2,int sy2,ImageObserver observer) to avoid the overhead of clipping.

One catch regarding this advice, is that under certain conditions there is a maximum texture size - beyond which HW acceleration will not occur.
This texture size limit is dependent upon several factors, including VM version, image type, and graphics drivers.

Regarding the alpha channel depth - it is almost always preferably to render a bitmasked image(1bit transparency), than one with a full alpha channel.(upto 8bit transparency).
The former will be accelerated on all 1.4+ Windows VMs, while the latter will require either a newer VM version, or several performance flags setting (to customize the rendering pipeline used).

Again, both aspects of this question have been covered *many* times before, if you want more thorough explanations, I suggest you try searching the forum.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline Kova

Senior Member





« Reply #9 - Posted 2006-11-16 22:09:11 »

no, the thing "we covered" isn't a issue here... you are talking about live subimaging (as I remember), where you need to extract image from bigger one every loop. Here you can do this at load time so timing isn't an issue. Now somebody answer this guy if it's good to use arrays like he did or is there something better Smiley

EDIT: I can think of simpler solution then original... you can still use your big tile palette  image and split it into few smaller ones that have common tiles. Like all tiles for player. They will get accelerated, then you can use drawImage(coords of inside tile) on them. This way you have few BufferedImages instead each for every tile (as you were afraid it will consume too much memory).

note: images with translucency aren't accelerated on windows, you should use translaccel=true property to accelerate them. You can just put "System.setProperty("sun.java2d.translaccel", "true");" at beginning of your program and it will work.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« Reply #10 - Posted 2006-11-17 10:24:23 »

Quote
just put "System.setProperty("sun.java2d.translaccel", "true");" at beginning of your program and it will work.

Taking the possibility away to remove it on systems where it does not work, and after all whats about platforms where Java2D is hosted on backends without accalerated translucency? Things aren't that easy, if you treat them like easy stuff you produce crap.

lg Clemens
Offline Kova

Senior Member





« Reply #11 - Posted 2006-11-17 19:56:53 »

Quote
just put "System.setProperty("sun.java2d.translaccel", "true");" at beginning of your program and it will work.

Taking the possibility away to remove it on systems where it does not work, and after all whats about platforms where Java2D is hosted on backends without accalerated translucency? Things aren't that easy, if you treat them like easy stuff you produce crap.

lg Clemens

wait a minute, I got impression that images with tranlucency aren't accelerated only in windows due to directdraw not doing it, so everywhere else (linux, solaris, ...?) it's accelerated (they use opengl?). Where else besides windows it dosen't work?
And if it dosen't work then nothing will happen right?
Offline Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #12 - Posted 2006-11-17 20:59:49 »

no, the thing "we covered" isn't a issue here... you are talking about live subimaging (as I remember), where you need to extract image from bigger one every loop. Here you can do this at load time so timing isn't an issue. Now somebody answer this guy if it's good to use arrays like he did or is there something better Smiley

...

The content of my original post *does* answer the original question.
It could have been clearer though, so i've restructured it so it better conveys its content.

To summarize, the poster had it right the first time - he was simply using unaccelerated 8bpp alpha translucency.

Changing to use bitmask transparency would have resolved the performance issues (either by altering the source image, or by coping the source image into a compatible BufferedImage with BITMASK transparency type)
Alternatively, they could enable the D3D or OGL pipelines to get accelerated full alpha rendering.

The former would give a more consistent speed increase across various VM versions, and platforms.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline Linuxhippy

Senior Member


Medals: 1


Java games rock!


« Reply #13 - Posted 2006-11-17 23:57:50 »

wait a minute, I got impression that images with tranlucency aren't accelerated only in windows due to directdraw not doing it, so everywhere else (linux, solaris, ...?) it's accelerated (they use opengl?). Where else besides windows it dosen't work?
And if it dosen't work then nothing will happen right?

On Linux and other Unices X11 is mostly used as backend for Java2D - currently Java doesn't support translucency on that backend. It will lead therefor to unplayable slow games. OpenGL is like ony windows only supported on a very limited range of driver/gpu combinations (mostly nvidia and worse ATI).
Bitmask transparency is definitivly the better choice here :-)

lg Clemens
Offline luisoft

JGO Coder


Projects: 6


Java games rock!


« Reply #14 - Posted 2006-11-18 00:03:23 »

I'm trying to use BITMASK stuff but it is not working

1  
2  
3  
      Image tmp = GameRepository.get().getImage(pImageName);
      this.image = new BufferedImage(tmp.getWidth(null),tmp.getHeight(null),BufferedImage.BITMASK);
      this.image.getGraphics().drawImage(tmp,0,0,null);


It is still very slow! If I change to BufferedImage.TYPE_INT_RGB then it becomes faster but then I cannot see my background because the transparency of the tiles were removed!

What should I try next? Huh


EDIT: Also tried the following

1  
this.image = Util.CONFIGURATION.createCompatibleImage(tmp.getWidth(null),tmp.getHeight(null),BufferedImage.BITMASK);


It is very slow to play it. Not using transparency I get 60FPS and can play ok. But I really want to have tile transparency and my background.
Offline fletchergames

Senior Member





« Reply #15 - Posted 2006-11-18 17:27:42 »

The image "tmp" already contains transparency, right?  When you draw it to this.image, the transparent pixels won't be drawn because they're transparent.  this.image shouldn't even look right unless there's some more code to fix that.

I don't think it will make any difference, but you should dispose the Graphics object as follows:

1  
2  
3  
Graphics g = this.image.getGraphics();
g.drawImage(tmp, 0, 0, null);
g.dispose();


Not disposing Graphics objects ties up system resources.

You do have to use the GraphicsConfiguration.createCompatibleImage method.
Offline Kova

Senior Member





« Reply #16 - Posted 2006-11-18 20:01:06 »

Not disposing Graphics objects ties up system resources.

as I remember they will be picked up by gc anyway, but it's a good thing to call dispose whenever those methodes exist, that probably make it easier for gc or something
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.

CogWheelz (18 views)
2014-07-30 21:08:39

Riven (23 views)
2014-07-29 18:09:19

Riven (15 views)
2014-07-29 18:08:52

Dwinin (12 views)
2014-07-29 10:59:34

E.R. Fleming (33 views)
2014-07-29 03:07:13

E.R. Fleming (12 views)
2014-07-29 03:06:25

pw (43 views)
2014-07-24 01:59:36

Riven (43 views)
2014-07-23 21:16:32

Riven (30 views)
2014-07-23 21:07:15

Riven (31 views)
2014-07-23 20:56:16
List of Learning Resources
by SilverTiger
2014-07-31 18:29:50

List of Learning Resources
by SilverTiger
2014-07-31 18:26:06

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

HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54
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!