Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (499)
Games in Android Showcase (118)
games submitted by our members
Games in WIP (567)
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 rendering with BufferedImage RGB data  (Read 1264 times)
0 Members and 1 Guest are viewing this topic.
Offline Vasari

Junior Newbie





« Posted 2013-06-18 03:15:38 »

I was wondering if I could obtain a buffered image and create another "psuedo" image from that by using the first image's color data to construct an image made up of 1 x 1 rectangles, representing the pixels of the buffered image. I'm not too sure if it would be faster than to use just regular buffered images. I figured it would be a different way of rendering and maybe get some performance gains.
Offline BurntPizza
« Reply #1 - Posted 2013-06-18 03:39:31 »

I'm not entirely sure what you're asking, but you can obtain the color data of a BufferedImage with this:
1  
 data = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

That will give you an integer array (you can change it to give a byte array, etc.), with each integer corresponding to the BufferedImage's type, e.g. TYPE_INT_ARGB for ARGB packed integers.

Modifying this array with also change the image, as it is a reference to the image's raster.
This should be faster than Graphics.drawSomething() for some operations, but it won't be huge. If you're concerned about performance, don't be using Java2D  Pointing
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #2 - Posted 2013-06-18 04:02:03 »

It may be a different way of rendering, but I don't think there would be any benefit, and in fact may be detrimental. It's a lot quicker to assign a color value to an array element (if pixel level manipulation is required) than to assign multiple values to a rectangle object. There are other reasons to avoid this approach, but in the end, you want to work with the API, not against, or around it.

As BurntPizza said, if performance is your top concern, consider a different API than Java2D. Personally, I haven't hit the wall with Java2D yet. I get around 1200+ FPS on a fairly modern machine at 1024x768 resolution with every pixel being touched during my rendering loop. Even my craptastic 7 year old laptop with integrated Intel video still manages to crank out 120 FPS in the same scenario. The only sure way to know is to try out a few different approaches, and see what works best for you. Smiley

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Vasari

Junior Newbie





« Reply #3 - Posted 2013-06-18 04:08:15 »

It may be a different way of rendering, but I don't think there would be any benefit, and in fact may be detrimental. It's a lot quicker to assign a color value to an array element (if pixel level manipulation is required) than to assign multiple values to a rectangle object. There are other reasons to avoid this approach, but in the end, you want to work with the API, not against, or around it.

As BurntPizza said, if performance is your top concern, consider a different API than Java2D. Personally, I haven't hit the wall with Java2D yet. I get around 1200+ FPS on a fairly modern machine at 1024x768 resolution with every pixel being touched during my rendering loop. Even my craptastic 7 year old laptop with integrated Intel video still manages to crank out 120 FPS in the same scenario. The only sure way to know is to try out a few different approaches, and see what works best for you. Smiley

Do you mind sharing your approach, it would be greatly appreciated. I've hit a huge wall and I'm sure there's something else I could do without having to move onto other API's. I would love to get that kind of performance at that resolution, but as soon as I start rendering a couple hundred images, the FPS starts sinking dramatically.
Offline BurntPizza
« Reply #4 - Posted 2013-06-18 04:10:32 »

I DO know that when finicking around in Java2D looking for performance, it is  very easy to 'trip a tripwire' and send the renderer into software rendering (making your image unmanaged), which vastly slows down everything. Another approach with Java2D is using BufferStrategy, which circumvents using BufferedImages, and, in my experience, is slightly faster. It is best used for fullscreen mode applications, however.
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #5 - Posted 2013-06-18 04:26:29 »

I don't do anything special. I mostly read up on Java's active rendering trail which covers BufferStrategy, as mentioned by BurntPizza, and implemented my rendering process accordingly. I've had good results in both full screen exclusive, and windowed mode. As a side note, I could have sworn that I read BufferStrategy uses BufferedImages behind the scenes, but I may be wrong.

According to the API docs, many of Java2D's transformation and blending functions are backed by the D3D or OpenGL subsystems when available. I attribute the high level of performance I see to this. Without knowing specifics though, the difference in performance between my experiences and yours could be due to the way you cache images (sprite sheets vs. individual images), differences in game loop logic, or any number of other things. I would say look through the docs to see if you may be doing something that's easy to correct. However, as BurntPizza said, there are some tripwires with using Java2D that could result in less than desirable performance in a given case. Maybe I've just been lucky in the fact that I haven't tripped enough of them to blow my performance to pieces. persecutioncomplex


Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline BurntPizza
« Reply #6 - Posted 2013-06-18 04:44:59 »

As a side note, I could have sworn that I read BufferStrategy uses BufferedImages behind the scenes, but I may be wrong.

It may, but either way, it takes care of it for you and it is likely to do it well, and that is nice.

Maybe I've just been lucky in the fact that I haven't tripped enough of them to blow my performance to pieces. persecutioncomplex

IIRC, I think it is mainly (or at least used to be) certain drawing operations (like transforms or compositing) or setData() etc, operations on buffered images that it didn't like.
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #7 - Posted 2013-06-18 04:50:36 »

These are the old 1.5 docs, but I think the data is still valid. I do definitely remember that pixel level manipulations prevent Java2D from accelerating the images.

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline BurntPizza
« Reply #8 - Posted 2013-06-18 04:57:36 »

Yea, it was mostly low level pixel operations that did that, but I believe that the .getRaster().getDataBuffer() etc. stuff does successfully get around this, albeit then you have to work with color packing and manually indexing and such. So for BufferedImages, that is the best option for pixel-by-pixel access to the image, am I correct?
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #9 - Posted 2013-06-18 05:12:47 »

I think you're correct. If I'm recalling correctly, which given the hour here I may not be, I think the preferred way to do direct pixel manipulations was to use create an image that was compatible with your BufferStrategy, then grab the pixel data for that image via the "raster/alpha data" methods and manipulate it. Once the pixel level manipulation was done, you render the final product to the back buffer and flip. This keeps the strategy itself accelerated even if the "scratch image" isn't. Direct manipulation of the back buffer is definitely a no-no. Shocked

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline BurntPizza
« Reply #10 - Posted 2013-06-18 05:18:40 »

I think you're correct. If I'm recalling correctly, which given the hour here I may not be, I think the preferred way to do direct pixel manipulations was to use create an image that was compatible with your BufferStrategy, then grab the pixel data for that image via the "raster/alpha data" methods and manipulate it. Once the pixel level manipulation was done, you render the final product to the back buffer and flip. This keeps the strategy itself accelerated even if the "scratch image" isn't. Direct manipulation of the back buffer is definitely a no-no. Shocked

Agreed. But using the pixel array should keep the scratch image accelerated and thus help with the process, otherwise not very many gains would be had, as you still have to render to the strategy.
Offline CodeHead

JGO Knight


Medals: 41


From rags to riches...to rags.


« Reply #11 - Posted 2013-06-18 05:30:45 »

According to this (admittedly older forum post), directly accessing the image data will most certainly un-accelerate your scratch image. It would seem to make sense, since that thread mentions Java having no real way of knowing what was modified and therefore no real way of knowing how to optimize the operations. I'm far from a guru on the subject though. I would love to find out a definitive answer from someone who has studied the rendering code a bit more since I have heard people say the same thing as you have. Excellent discussion. Grin

Arthur: Are all men from the future loud-mouthed braggarts?
Ash: Nope. Just me baby...Just me.
Offline davedes
« Reply #12 - Posted 2013-06-18 12:13:45 »

However, as BurntPizza said, there are some tripwires with using Java2D that could result in less than desirable performance in a given case. Maybe I've just been lucky in the fact that I haven't tripped enough of them to blow my performance to pieces. persecutioncomplex
The main problem with Java2D's performance is that it's extremely unreliable. Your test machines might be giving you high performance, but any number of other test machines might slow to a crawl. You have very little control over what pipeline it chooses, or whether it uses hardware acceleration as you would expect (or at all).

I have seen this happen where my professor could only run my game at 2 FPS; even though I was getting 60+ FPS on my own test devices. His computer was pretty new and had good specs.

In the end; if you hope to target more than just your own computers, it's not worth risking it with Java2D. Wink

Offline nhydock

Junior Member


Medals: 4
Projects: 2



« Reply #13 - Posted 2013-06-18 15:04:30 »

When it came to changing the pixels of a BufferedImage, I just took the shortcut way and always did getGraphics() then drew directly to it while keeping a backup of the original loaded image somewhere in memory.  Of course I only did this occasionally due to the memory duplication.

Java2D does give you direct control over which pipeline you can use and what settings http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html#gcghe

Only thing I can really recommend if you want to increase performance in your Java2D game is to be sure that anything off screen you systematically cull. If you're not accounting for the frame's dimensions and your current camera location, in your render loop you might still be rendering things that are not even being seen.
Offline davedes
« Reply #14 - Posted 2013-06-18 15:35:28 »

Java2D does give you direct control over which pipeline you can use and what settings http://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-Desktop/html/java2d.html#gcghe
You can request it, but no guarantees. Also notice on Mac, the VM flags don't have any effect (at least not in any of my tests). You just need to hope it's using hardware acceleration; and not doing anything stupid under the hood.

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.

Pippogeek (36 views)
2014-09-24 16:13:29

Pippogeek (29 views)
2014-09-24 16:12:22

Pippogeek (18 views)
2014-09-24 16:12:06

Grunnt (41 views)
2014-09-23 14:38:19

radar3301 (24 views)
2014-09-21 23:33:17

BurntPizza (60 views)
2014-09-21 02:42:18

BurntPizza (30 views)
2014-09-21 01:30:30

moogie (35 views)
2014-09-21 00:26:15

UprightPath (48 views)
2014-09-20 20:14:06

BurntPizza (52 views)
2014-09-19 03:14:18
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!