Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
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  
  Pixel Array Manipulation vs. Multiple DrawImage Calls  (Read 1009 times)
0 Members and 1 Guest are viewing this topic.
Offline BlazeCrate

Innocent Bystander





« Posted 2014-04-06 20:27:53 »

Hello,

This is a question that I have had for a while. I am wondering if it is faster for a Java game to do rendering with a pixels array of integers and then update the pixels based on that. Another option is to use the Java2D Graphics class and create multiple bufferedimage's and then call g.drawImage multiple times.

Overall, My question is: Is it faster to in the long run to manipulate a pixels array of integers for each rendering call that you make or is faster to call g.drawImage(); multiple times to render each bufferedimage that you create?

Thanks
Offline hwinwuzhere
« Reply #1 - Posted 2014-04-06 20:41:16 »

I personally use pixel manipulation. That is because it is really powerfull in comparison with drawImage calls. I made a few tests on this and found out that after several drawImage calls my fps dropped really badly. Rendering everything pixel by pixel (if done well) gives you more control over the end product, and gives more performance.

When doing more complicated things such as lighting or particles I found it more usefull to manipulate each pixel than to use the drawImage function. I got more precise results out of it.

What did the boolean say to the integer? You can't handle the truth.
Offline BurntPizza
« Reply #2 - Posted 2014-04-06 20:47:23 »

Please use the search bar.

Quick rundown:

First, do you need more performance? Is your renderer struggling? If not, don't even ask this question.

Second, the two different methods serve different purposes: if you need to blit (draw) and image onto another (or the screen) drawImage is the way to go, and the fastest thing there is.
If you need to calculate each pixel individually (dynamic shadows, etc), then a pixel array is the way to go, the only alternative being lots of drawLine(x,y,x,y) calls.

So use a pixel array if the task cannot be done with drawImage, not just on a whim. Simplify your life.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline jonjava
« Reply #3 - Posted 2014-04-07 02:57:17 »

Both use AWT. There's no reason to use one instead of the other. You can use both.

Offline BurntPizza
« Reply #4 - Posted 2014-04-07 03:07:46 »

Both use AWT. There's no reason to use one instead of the other. You can use both.

I believe by "pixels array of integers" he means
int[] data = ((DataBufferInt)image.getData().getDataBuffer()).getData();
and then manipulating
data
, which in fact does not use AWT, at least directly (you still have to draw the
image
after playing with the array)

Although yes, you can certainly use both. They have different use cases; I'm not even sure why you would ever mess with an array to draw an image if 1. you already have an image, 2. with the array you have to draw the image afterwards anyway. Maybe I don't completely understand OP's question.
Offline jonjava
« Reply #5 - Posted 2014-04-07 04:59:54 »

Exactly. You'll have to draw the image in the end anyway (using AWT).

The overhead you're sidestepping is doing a bunch of g.drawImage calls which in most cases won't matter at all. There was a post about Swings behavior a while back - couldn't find it.

Point is, sidestep the g.call overhead only if you have to -and if you are at a point where you have to - you're either doing something very, very wrong or you should be using something much more robust (e.g., openGL).

The only other reason to manually manipulate the pixels are because of interest or boredom. A fine but somewhat redundant form of mental masturbation if only for pedagogical reasons.

Offline hwinwuzhere
« Reply #6 - Posted 2014-04-07 09:44:00 »

The only other reason to manually manipulate the pixels are because of interest or boredom.

Might indeed be the reason I use it Smiley

What did the boolean say to the integer? You can't handle the truth.
Offline nsigma
« Reply #7 - Posted 2014-04-07 10:51:22 »

Second, the two different methods serve different purposes: if you need to blit (draw) and image onto another (or the screen) drawImage is the way to go, and the fastest thing there is.

If you're blitting onto another BufferedImage then that statement isn't true. Direct pixel manipulation is at least as fast and often faster - it's exactly what the Graphics2D will be doing, but with less overhead. If you're rendering to the screen or VolatileImage then drawImage will be much faster. The answer to the question depends on where the images are being drawn to.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline hwinwuzhere
« Reply #8 - Posted 2014-04-07 11:38:09 »

Let's make an example:

We're running a game on 120 fps. Every frame I use 1 drawImage call (to put the final image to the screen). That image is contructed from a data array in which I've been working in since my last render cycle. Once the render is complete (i.e. I put all pixels in the right place of my data array) I use the drawImage call mentioned above. I've found that this is alot faster than using a drawImage call for every tile/object/mob/entity/etc.

What did the boolean say to the integer? You can't handle the truth.
Offline Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #9 - Posted 2014-04-07 14:10:09 »

The answer to the question depends on where the images are being drawn to.

... and from.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StumpyStrust
« Reply #10 - Posted 2014-04-07 22:11:16 »

I have found that the easiest, simplest, and for the most part fastest way to draw an image is via the "blit". If this is accelerated, it should be faster then direct manipulation.

2 reasons.

1. If it is accelerated, it will use opengl/directx which is faster then software rasterizing which is pixel manipulation.

2. Software rasterizing is slow. It will be faster then the "blit" if the "blit" is not accelerated as it will default to rasterization.
 
What can drop acceleration from images:

First you should be drawing using a buffer strategy or a volatile image. Drawing with a buffered images graphics object is not accelerated.

Grabbing the pixels from a bufferedimage will drop it from being accelerated. It is also slow.

Certain operations when drawing bufferedimages/volatile images drop into software. Things like drawArea/shape and different filtering settings. (AA, bi-cubic filtering, custom alpha composites)

Pixel manipulation via grabbing a buffered images pixels once, manipulating them and then drawing said buffered image will be faster if you want to do things that will drop acceleration as you can optimize better then the fall back the Java2D uses. 

Offline BurntPizza
« Reply #11 - Posted 2014-04-07 22:14:21 »

Drawing with a buffered images graphics object is not accelerated.

Grabbing the pixels from a bufferedimage will drop it from being accelerated. It is also slow.

These seem rather contradictory, and I'm pretty sure the former is false. Hold on while I find some documentation.

EDIT: Not a lot of recent, up-to-date, or well tested data out there it seems.

Some other people's opinions/findings:
http://stackoverflow.com/questions/4627320/java-hardware-acceleration
http://stackoverflow.com/questions/2374321/how-can-i-create-a-hardware-accelerated-image-with-java2d
http://www.jhlabs.com/ip/managed_images.html (don't know how recent)

So it's muddled still, but it seems that most things are accelerated on a BI, while a few things like Stumpy said are bad and will "decelerate" the image.
Offline phu004

JGO Coder


Medals: 4
Projects: 9
Exp: 10 years


NoSuchPersonException


« Reply #12 - Posted 2014-04-07 23:38:10 »

Quote
Overall, My question is: Is it faster to in the long run to manipulate a pixels array of integers for each rendering call that you make or is faster to call g.drawImage(); multiple times to render each bufferedimage that you create?

If you only draw a couple of images, using drawImage() woule be faster. However if you plan to draw thousands of images (especially small images),  you are better off to "draw" all pixels to the bufferedImage.  This way your only call drawImage()  once rather than thousands of times.  
Offline StumpyStrust
« Reply #13 - Posted 2014-04-08 00:41:53 »

Here, try drawing with a bufferedimage's graphics object and then try drawing with a volatile image's graphics contex. You can draw your own conclusion.

All BufferedImages are "Managed" Images be default. That is they start accelerated. You can draw buffered images onto accelerated surfaces quickly. An accelerated surface is basically a VolatileImage. You cannot draw to a bufferedimage quickly as it is not an accelerated surface.

In pseudo opengl:

BufferedImage  = texture
VolatileImage = FBO/render target
Buffered Strategy is backed by a Volatile Image a believe.

So drawing to a texture that is not set up to be drawn to is slow.

BufferedImages support AA/filtering/other such effects. Some are slower then others. Shape/polygon rendering is slower then image bliting.

VolatileImages can be drawn as well but not all operations are "fast".

All of this also depends on ones drivers as well.

I have done extensive trial and error testing much of this in my Retro project. So my proof behind what I say is not from documentation but experience. Realistically, NO one should be using java2D for anything other then a 4k contest.

Pages: [1]
  ignore  |  Print  
 
 

 

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

The first screenshot will be displayed as a thumbnail.

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

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

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

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

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

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

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

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

Riven (28 views)
2014-07-23 20:56:16

ctomni231 (59 views)
2014-07-18 06:55:21
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

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
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!