FPS: what's the expectation?

Greets, all.

I promise to you all that in the next few months I will be very much more active… no secret I’m writing a game, but I prefer to wait before getting into the innards.

So I want to ask a question, and I am seriously hoping I don’t start a flame session here… there are reasons for asking the way I am.

I’m forced, unfortunately, to support JDK 1.3.1 at the moment. Mac support is critical to what I am working on, and believe me, it is the FIRST THING I am getting rid of once Apple releases the final on 1.4.1. So I’m screwed as far as animation is concerned… I have to put up with whatever I can get in 1.3.1.

This means that I have largely depended on the expertise of you fine folk. Your insights have been VERY critical to designing fast, clean code. However, I think I have a rather nasty problem lurking.

Everything works currently, but it’s being tested this week with multiple sprites… and I am extremely nervous. We currently use 8 frames of image… and want to display said 8 frames in one second… now the quirky thing is that the timing is WAAAAY off when you compare the Mac versus the PC… I attribute this to a difference in the timers, even allowing for the “timer hack” so graciously provided by TheLorax (thanks for posting it again, Jeff).

So here’s where I am not following: in 1.3.1, I realize I do not gain any acceleration benefits, I don’t get VolatileImage, and what I DO get is BufferedImage, unaccelerated. I’ve preloaded my images, and I redraw my backgrounds once per second, and use a single g.drawImage for every frame I render from one of two flip buffers till we’ve loaded the alternate one. Put another way, we draw background once, and the moment you start moving, we draw into the second background buffer while we keep sliding in a direction from the first one. Flip once we’re at a tile boundary. Unfortunately you can’t do this for sprites, so you are forced to draw sprites EVERY render.

The big question is, how many frames can I expect UNACCELERATED JAVA to be able to produce in a second? I keep hearing of the 400 fps demo in 1.4, I’ve personally seen games running 120-180 fps, and yet I don’t think I can display any more than 8. EIGHT. That’s a BIG disparity.

And with that kind of a disparity, I’m forced to ask: do the changes from 1.3 to 1.4 REALLY make that much of a difference as to give you a 10 to 1 speed increase?

What am I missing here in my bid to take over the gaming world? (just kidding, btw).

Your help is greatly appreciated.

The main thing in 1.4 which affects the framerate that much is the acceleration of offscreen images. That is, there is a way now to store your images (sprites and the backbuffer) in the vram, and then use video board’s hardware to copy them around. This is WAY faster than copying from system memory to the screen.

Then, there’s the FullScreen API - your app can now run in full screen mode, and BufferStrategy, which allows use of buffer flipping, which is even faster than vram-vram blit.

For more info, take a look at
http://java.sun.com/products/java-media/2D/perf_graphics.html

trembovetski,

Thanks for taking the time to answer… I really do appreciate it.

Now, what happens (I know this was asked recently but I don’t think I understood the answer) in the case when you don’t want to run in fullscreen mode? My game client is designed for 800x600, but I’m not sure I want to throw the monitor into that mode forced… so I know I’m not vsync-refresh locked on the display (which would be what, 60fps?), but what else do I lose by staying in the windowing mode?

Also, is a vram-vram blit really that much faster? That it might result in 8fps to 80 fps? I have a hard time believing that considering that VRAM is not really running much faster than system RAM, and that I can’t see a system bus transfer from one RAM to another RAM (what I assume I end up doing in 1.3.1 using g.drawImage() now) is THAT slow.

Or am I off my rocker?

Just read the article you posted… and it did make me think that perhaps one BIG thing I need to understand is my own code. I wonder if I’m creating the right images? I wonder if I am doing something that slows me down? Profiling, profiling, profiling.

Gots to read the article on creating images again… anyone have that link anymore?

The point about vRam->vRam is that it’s using separate, dedicated hardware. So the CPU can set it off and then continue with whatevers up next. Contrast that with system->vRam (which would be done at the end of each frame otherwise) which is incredably slow comparativly.

The other point about VRAM->VRAM is the -> bit, often overlooked, which is a bus transfer of the data. When the bus is a super-fast internal little thing sat on the graphics card itself you’re going as fast as can be. But a system RAM blit has to grab the data out of system RAM, up to the CPU, and then back down the AGP or even PCI bus to the graphics card, which then has to munge it into its own memory. You can see that’d be a lot slower, and yes, 10x slower in fact.

In 1.3, you are shafted, performance-wise, and there’s nothing you can do about it. The only reasonable piece of advice is this: if you’re using Java because it’s cross platform, deploy it on the biggest platform first, which is Windows, under 1.4.1. Wait a little while for the Mac 1.4 port. You can always busy yourself with getting Linux to work in the meantime.

If you’re using Java just because you like the language and want to write a Mac game, you remain in your shafted state, and will likely go insane, or eat your toes, or stick pins in effigies of Gosling.

Cas :slight_smile:

btw if you are a member of the Apple Developers Connection (free for th basic mmbrship) you can get the beta of 1.4.1. It needs x.2, but at least it’s there.

John

VRAM is much faster: faster clock, 128bit bus (new ones even 256), dedicated HW-unit for blitting, possibly running paralel with the CPU.

The Windows-JAVA1.3 had terrible problems with Images that were allocated with Transparency.BITMASK, use TRANSLUCENT on Java1.3, if you need any transparency at all. But be sure to use BITMASK when you detect a 1.4 java. Don’t know if there are BITMASK problems on Mac-Java 1.3

I use a 1.1 JVM for most of my games (applet).

Some are as big as 600*480 and I can definitly push more than 8 fps (I would say… around 35 fps for a common game running around 64 sprites).

And I’m certainly not using all the features I could (mainly because I haven’t found them yet).

I know many high performance game developper get ride of the classic way of drawing frame and do everything into with a MemoryImageSource as the pixel buffer and draw pixel by pixel themselves.

On another subject, I’m looking into GBA (game boy advance) developpement right now (quite interresting and well though piece of gaming hardware).

Is there a way to catch the Vertical Blank moment in java? (1.1 if possible…)
Under gba, you use that time to do all your update… and I’m starting to think of a new game engine very similar to the gba hardware…

Thanks,

Seb

Thanks to all for your responses!

I’m proud to be part of such a great group; I wish I would be more help here and there!

So I see that for the present, we’re hosed since we’re on 1.3.1. And I think I understand what we’re experiencing a problem with…

… but that still doesn’t fully explain getting only 8fps unless I don’t know what I’m doing as far as blitting goes.

Can someone explain how they are achieving 35fps in 1.1? My game screen is a 512x512 panel that has its own thread animating it.

Also, Orangy, you mentioned that vram-vram is what happens in 1.4.1… but isn’t there an initial copy when you first dump data? And what happens when the vram cache is dirty? Are you also doing a system->vram copy at that point, and what does it do to your framerate?

[quote]Can someone explain how they are achieving 35fps in 1.1? My game screen is a 512x512 panel that has its own thread animating it.
[/quote]
By doing the blitting/drawing yourself into a MemoryImageSource or (for Java2) a BufferedImage (pixel per pixel). I get up to 45fps @512*512 when doing perspective correct, filtered and gouraud-shaded texture-mapping using this method (that’s on an Athlon XP 2000+).

Egon,

Thanks, but I still don’t get it. What’s the difference between just using a BufferedImage and drawing pixel per pixel on a BufferedImage?

Are you trying to avoid using the g.drawImage() using this technique?

[quote]Are you trying to avoid using the g.drawImage() using this technique?
[/quote]
Yes…you are basically trying to avoid all g.drawStuff()s using this method. The drawback is that you are on your own and sometimes have to reinvent the wheel.

Hmmmmmmmmmmmmmmmmmmmmmm.

I wonder how much faster this might be.

I just changed over some image creation stuff to using Transparency.TRANSLUCENT and not using new BufferedImage() but I got no help there.

I wonder… is there any example of doing your own copying instead of drawImage()?

[quote]I wonder how much faster this might be.
I wonder… is there any example of doing your own copying instead of drawImage()?
[/quote]
I hacked together a little applet:
http://www.jpct.net/test/
I uses the 2d blitting methods my 3d engine offers, so it comes with the complete engine in a JAR. That’s why it is around 100K in size…the actual 2d blitting code alone would be MUCH smaller.
I displays 30 sprites (6464 each) on a 512512*24bpp framebuffer. Black pixels of the sprites are transparent.
It uses a MemoryImageSource when running under 1.1 and a BufferedImage for JAVA2.

Holy cow, that’s incredible!

Using the 1.3 plug-in I’m getting 51fps! That’s what I need!

Any chance I can see the source code?

I hope I have not confused you:
Only use TRANSLUCENT for images that actually need transparency, for all other use OPAQUE. And make an image creation subroutine that checks if the java version is 1.4 or better, then use BITMASK for images that need transparency.
And as I said: I don’t know if BITMASK makes problem on the Mac.

I once made a thread in the old forum about it and wrote a very short demo applet that does nothing else than blitting stuff:
http://www.zoncon.com/various/testcase1/TestCase.html

It might give you a hint which image might be fastest on your JVM. And watch closely if the BITMASK blit looks different than the TRANSLUCENT blit (looks same as expected on 1.4, but different on 1.3)

The 1.4 plug-in in my browser reports a 4 to 1 speed improvement by using BITMASK as opposed to TRANSLUCENT. I still have to figure out what happens in 1.3…

It’s part of the engine, so this would be difficult. Anyway, i tried to type some code fragments out of my head for BufferedImage. Note that this won’t compile or anything…it’s just to show the basic principle (using a BufferedImage only, MemoryImageSource is slightly different):


BufferedImage output = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
DataBufferInt data = (DataBufferInt) output.getRaster().getDataBuffer();
int[] pixels = data.getData();   // the destination bitmap
int[] src = *the source-bitmap (the sprite) in RGB*

startDest = *where the blitting starts in the destination bitmap*;
startSrc = *where the blitting starts in the source bitmap

for (int y=0; y<ySize; y++) {                       
  for (int x=0; x<xSize; x++) {                            
      pixels[startDest+x]=src[startSrc+x];                        
  }                        
  startDest+=width;                        
  startSrc+=srcWidth;                    
}

....

g.drawImage(output, 0, 0, null);

This code lacks clipping and transparency-handling and and and…but maybe you get the idea.

Edit: I changed the sprite in the applet. Using 24bpp for a single colored sprite is rather senseless.

Many thanks, Egon. I will consider doing this myself, but it might not be worth the effort just yet if 1.4.1 is so close on the Mac.

I did run the test applet Themroc graciously provided: there is almost 4 to 1 decrease in speed by using 1.3 instead of 1.4… at one point drawing was approaching 2 seconds! Ouch.

I see now there is a big difference in images that are VRAM cached versus in system memory. However, that latest post about getting 35 fps in 1.3 really scared me, and I started a new thread regarding drawing loops… If I cannot make it past 8fps I think I have much bigger problems to worry about, like the effectiveness of my rendering code.

I was extremely impressed by Egon’s demo with the fast blitting, (i got like 100fps and it was very smoothe), but i wanted to compare with IE’s JVM…The good news is that IE got about 50 fps, the bad news is that while the IE JVM was running the applet, the plugin could not execute (or it was executing at like 1fps when I managed to get the web-page loaded). Maybe it’s a flaw in the plugin, or maybe Ie knows how to grab all the processor from other processes.

-Chris