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 [2]
  ignore  |  Print  
  Awesome Speeds With VolatileImage  (Read 10470 times)
0 Members and 1 Guest are viewing this topic.
Offline StumpyStrust
« Reply #30 - Posted 2012-10-27 18:31:26 »

Lets just sum this up and make things easy. If you want any form of performance in java2D, you can never grab the pixel array of a bufferedImage every frame.

If you want to do some sort of lighting, then there are other ways of doing it that are much fast. (look at the Toxic Bunny dev blog for details)  If you want to do post processing effects, move to opengl. The best I go with a basic bloom filter was really hacky and very slow.

Offline nsigma
« Reply #31 - Posted 2012-10-27 18:58:17 »

Lets just sum this up and make things easy. If you want any form of performance in java2D, you can never grab the pixel array of a bufferedImage every frame.

If you were attempting to sum up what I was saying, you got it opposite!  Tongue

Every time you modify a BufferedImage it happens in software.  One of the fastest and most flexible ways to modify a BufferedImage is to grab the pixel array.  Grabbing it every frame has no performance penalty over other methods of modifying it, and can often be faster!  A pity the PulpCore project is discontinued, because this was a good example of pure software rendering in Java, and how direct array manipulation was often faster than the Java2D software pipeline (search Bubblemark on here!).

What I was saying is that if you want to grab the array of an image (sprite) and change it, then draw it lots of times unchanged, you should draw it into another BufferedImage so it can be re-managed.  

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Oskuro

JGO Knight


Medals: 39
Exp: 6 years


Coding in Style


« Reply #32 - Posted 2012-10-27 20:38:12 »

Thanks for the replies.

Now, I do understand that if I'm meddling with the internal structure, it is being handled by the CPU.

From what you've explained, I'm guessing the usual way to draw graphics is to keep the graphic elements in VRAM (say, sprites and backgrounds) and composite (copy into frame) from said copies.

I also understand that certain operations (rotation, scaling, shearing...) need to be supported by the GPU or else the images will be dumped back into Software mode.

Now, as far as sprites, tiles or GUI is concerned, that seems easy to handle.

What I am somewhat concerned is with full-screen effects.

One example is the static filter I'm using for testing, other would be screen glows, or using masks to apply lighting effects...

On one hand I've read that blitting of alpha-enabled images isn't always supported by the GPU, so creating masks as BufferdImages and then applying them might not be a good way to do it.

On the other had, some effects might need per-pixel control (Static being an example, although I can think of a few ways to simulate static with a set of pre-calculated alpha masks).

So how would you suggest these are handled? (And AWT not being able to do these things reliably is a valid answer)


For the record, I'm inquiring now because I'm building the rendering pipeline as I learn, better to decide now on this than backtrack later.

Also, I've noticed slowdowns when experimenting with large resolutions. My target game resolution is around 320x200, so the CPU will probably be able to handle it. This VolatileImage discussion is mostly educational for me.

And again, thanks for your time.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline StumpyStrust
« Reply #33 - Posted 2012-10-27 23:56:19 »

Scaling has very little performance penalty if any. Rotating will drop performance but will be fine as long as you are not rotating 500-1000 sprites every frame. I think just about all gpu from the last 5 years should support the rotation, scaling, and shearing.

Lets just sum this up and make things easy. If you want any form of performance in java2D, you can never grab the pixel array of a bufferedImage every frame.
If you were attempting to sum up what I was saying, you got it opposite!  Tongue


I meant modifying the pixels. You can grab them and be ok but if you want to edit them and do something then you are SOL unless there are some tricks that I do not know of.

The idea of drawing to another bufferImage/volatileimage is good if you only do it on start up or maybe one time when a level is loaded. Doing it every frame will kill performance. I used this technique for my bloom filter and it gave a nice speed boost but not enough to get higher then 35fps.

What do you mean by blitting? Are you talking about alpha blending? Then again, you should be fine. Most gpu and even integrated chips support alpha blending. So you should not need any form of mask.

I am not sure what you mean by fullscreen effects. What is the static filter? Adding what looks like static to the game? like an old TV. Screen glow would be bloom? Lighting?

Java2D can draw images very well. You can simulate a lot of cool effects with just drawing an image and using clipping such as lighting.

I would suggest a low resolution (which you have) and making it so the target fps is 24-30 fps. You might be able to manage doing some of these things at that low of a frame rate. If you really want to do all of this in java2D look at Toxic Bunny dev blog. They show what they did to get all of the effects they have. (lighting being the big one)

Offline Oskuro

JGO Knight


Medals: 39
Exp: 6 years


Coding in Style


« Reply #34 - Posted 2012-10-28 01:10:11 »

Blitting is the composition of several bitmaps by means of a raster operation (As defined by wikipedia).

I was refering to hardware blitting as explained here. Meaning how the GPU combines volatile images without making software copies.

As for "fullscreen effects", the proper term probably is "post-processing filters" meaning stuff you do to arbitrary portions of the screen independently of content.

An example is a simple "glow" effect made by increasing the lightness component of all pixels on the screen to make it flash.

The static effect yes, simulates typical white noise type static you get on TVs, it is done by randomly altering the lightness of every pixel, something like this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
for(int i = 0; i < bufferPixelArray.length; i++)
{
  int pixel = bufferPixelArray[i];

  int randomNoise = random.nextInt(16) * 5;
  int lightLevel = 100;  
           
  //Compute pixel illumination + static filter
 int valueRed    = ((pixel >> 16)  & 0xFF) * lightLevel / 255 + randomNoise;
  int valueGreen = ((pixel >> 8)    & 0xFF) * lightLevel / 255 + randomNoise;
  int valueBlue   = ((pixel)           & 0xFF) * lightLevel / 255 + randomNoise;
   
   
  int finalColor = valueRed << 16 | valueGreen << 8 | valueBlue;

  bufferPixelArray[i] = finalColor;       // Assign RGB data to pixel

}


I doubt this can really be accelerated, unless the code can somehow be run on the GPU.

On the other hand, maybe this effect or rudimentary lighting can be achieved by rendering the light mask into a low resolution image (say at half resolution) and then attempt to have the GPU blit the image into the main frame, combining alpha values.

If it worked, It'd make for pixelated effects, though.

Offline Riven
« League of Dukes »

JGO Overlord


Medals: 801
Projects: 4
Exp: 16 years


Hand over your head.


« Reply #35 - Posted 2012-10-28 01:33:45 »

Create a big texture with noise, and sample it with your shader, with random offsets each frame.

Hi, appreciate more people! Σ ♥ = ¾
Learn how to award medals... and work your way up the social rankings
Offline StumpyStrust
« Reply #36 - Posted 2012-10-28 05:05:26 »

Riven this is in java2D there are not shaders.

Oskuro, that is what I thought you meant but there really is no major performance gain from blitting vs just drawing. If there is some, it is not the major bottle neck. The pixel manipulation is your bottle neck.

One idea for the static effect is to have 3-4 images that have bits of static in them and the rest transparent and composite them randomly on the screen. This will give you a similar effect and be very very fast.

You can do the glow effect by rendering a white semi transparent square over the whole window.

Java2D does not do additive blending and if you want to do that then you will have to un-accelerate your drawing surface.

Most effects you will have to fake because java2D was not designed to do them. The lighting being draw onto a smaller map is what I did with some things and it can greatly improve performance. If you use bi linear filtering you can go to 1/3 the resolution and still get fairly good looking lights.

Using a volatile image as a FBO or Texture (not quite sure which one is more accurate) is great and I am not sure if you know about the getSnapShot() method that will give you a bufferedImage of the volatile. This is useful as you can then edit it the pixels you just drew and render them on to your main drawing surface. Think of light maps.

If you really want to do all sorts of cool post processing effects, java2D is not the way to go. At this point with how well you understand everything, you should have no problem getting into opengl or libgdx. I do not know how much you have put into this but it sounds like you want to get going with shaders. (something I am strangling myself with)

Offline nsigma
« Reply #37 - Posted 2012-10-28 10:02:45 »

Lets just sum this up and make things easy. If you want any form of performance in java2D, you can never grab the pixel array of a bufferedImage every frame.
If you were attempting to sum up what I was saying, you got it opposite!  Tongue
I meant modifying the pixels. You can grab them and be ok but if you want to edit them ...

So did I!  Kind of getting the feeling we're speaking different languages here?!  Tongue

Directly updating / editing the pixel array of a BufferedImage every frame is actually pretty fast, and it's possible to do this faster (a lot in some cases) than the software Java2D pipeline.  If you do this, you should just ignore everything about managed images because they never will or can be managed.

Personally, I'd ignore Java2D as much as possible for anything requiring consistent framerates, performance, etc.  It's great for UI's, but it's too unpredictable for many uses, and favours accuracy over performance too much.

If you want consistent(ish) hardware rendering, use libGDX or similar.  If you want to work with software rendering and pixel operations in Java, just grab the pixel array of a BufferedImage, play with it, and draw it to a BufferStrategy every frame.  It's a usable solution for low / medium resolution stuff as long as you don't go overboard, and performance is far more predictable.

The idea of drawing to another bufferImage/volatileimage is good if you only do it on start up or maybe one time when a level is loaded. Doing it every frame will kill performance. I used this technique for my bloom filter and it gave a nice speed boost but not enough to get higher then 35fps.

Doing it every frame is precisely what I said not to do (at least if you're only drawing it once)!  You're just needlessly copying an entire pixel array in Java before it gets streamed to the graphics card.  It is potentially worth doing if you need to transform the image when you draw it, but only if you use a VolatileImage.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline nsigma
« Reply #38 - Posted 2012-10-28 10:38:42 »

Blitting is the composition of several bitmaps by means of a raster operation (As defined by wikipedia).

If you're going to stick with the software rendering route, and are just doing plain blitting (no scaling), I'd also recommend looking at this thread - lots of fast blend modes (Add, Multiply, Difference, etc.) for combining the pixel arrays from BufferedImages (or similar).  The code derives from Praxis' software pipeline, but was extended and developed further by Dx4 (he also changed to work with single source pixels, which I disagree with).  Using these is faster than using drawImage() on a BufferedImage.

The static effect yes, simulates typical white noise type static you get on TVs, it is done by randomly altering the lightness of every pixel, something like this:

Looks interesting.  There are a few ways you could speed that up though.  Primarily replacing the use of random with a much faster performing (though less random  Smiley ) alternative.

I'm using this which outputs between 0 and 255 - can't remember where the algorithm came from originally

1  
2  
3  
4  
5  
private static int rngseed = 0;
public static int random() {
    rngseed = rngseed * 1103515245 + 12345;
    return ((rngseed >> 16) & 0xFF);
}


You could also replace divisions by 255 with >>8.

Check out the mult() and multRGB() methods here - http://code.google.com/p/praxis/source/browse/ripl/src/net/neilcsmith/ripl/rgbmath/RGBMath.java  NB.  This will move with my next code commit.

I doubt this can really be accelerated, unless the code can somehow be run on the GPU.

Well, one day we'll see Java code running on the GPU - http://openjdk.java.net/projects/sumatra/.   Wink  In fact, it's doable now with Aparapi.  But seriously, if you want to get it running on the GPU, it's time to dive into GLSL.

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Offline Oskuro

JGO Knight


Medals: 39
Exp: 6 years


Coding in Style


« Reply #39 - Posted 2012-10-28 14:19:34 »

Thanks for all the replies.

As I've said, I'm mostly learning the basics of graphics rendering. The use of Java is merely incidental, as I often strip out parts of the standard java classes I have no interest in using. My point is to try and develop a graphics pipeline that would work equally well (with minor library changes) if I were to port the code to other language, or to a different Java implementation, hence the interest in manipulating data buffers as directly as possible.

My main concern is what strategies to use when approaching rendering of different elements. From this thread I gather the following:

  • When dealing with concrete resources (Sprites, backgrounds, etc) it is best to load them as BufferedImages and compose them together without modification, so the system accelerates them if possible
  • When dealing with direct manipulation, minimize by reducing resolution or framerate, and whenever an effect is going to remain static for a while (say, the glow around the player when holding a lamp, which will always be the same for as long as the player has that specific lamp) it is best to render it into a texture to be handled as a concrete resource.

I will eventually move into better rendering solutions, right now I just want to try doing things by hand to wrap my mind around how things work under the hood, so to speak.

Also, my first project is meant to be retro-limited, as in low resolution, lack of fancy effect and the like.

Possible follow-up projects I may develop to run on my Blackberry (with no OpenGL support), so it is important I learn to handle things as low level as possible.

In any case, thanks for all the information! It is hard enough to find out information on the net that doesn't directly tell you to use this or that library, so these threads are gold to me! Cheesy

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Oskuro

JGO Knight


Medals: 39
Exp: 6 years


Coding in Style


« Reply #40 - Posted 2012-10-28 22:31:56 »

Word of advice to anyone wanting to meddle with the internal buffer on a BufferedImage:

1  
2  
3  
4  
5  
//This works (for <type> being int, byte or short, and <Type> being Int, Byte or Ushort)
<type>[] bufferData = ((java.awt.image.DataBuffer<Type>)BufferedImage.getRaster().getDataBuffer()).getData();

//This, on the other hand, does not (The BufferImage.getData() method creates a copy of the buffer, that is not backed up by the actual image.
<type>[] bufferData = ((java.awt.image.DataBuffer<Type>)BufferedImage.getData().getDataBuffer()).getData();


Yes, I spent all day today wondering why my filters where not working.  Clueless

Edit: Corrected typo on data buffer types. It's java.awt.image.DataBufferUshort, not DataBufferShort

Offline gimbal

JGO Knight


Medals: 25



« Reply #41 - Posted 2012-10-29 13:41:05 »

Perhaps you already knew, but directly accessing the raster of a BufferedImage tends to make it so the image cannot be accelerated anymore.
Offline nsigma
« Reply #42 - Posted 2012-10-29 14:04:46 »

Perhaps you already knew, but directly accessing the raster of a BufferedImage tends to make it so the image cannot be accelerated anymore.

Wow!  Did you read any of the last page?  You might find why that point is irrelevant!  Tongue

Praxis LIVE - open-source intermedia toolkit and live interactive visual editor
Digital Prisoners - interactive spaces and projections
Pages: 1 [2]
  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 (37 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 (42 views)
2014-09-23 14:38:19

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

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

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

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

UprightPath (49 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!