fps and pausing technique again...

i know this is a very common problem, but even the forum search did not result in an answer.

i digged my old arkanoid out of its grave to work it completely over. the very first thing to do is getting smooth animations.
please keep in mind, that this is a first attempt not a final construct:



public static final int FRAME_RATE = 85;
public static int FRAME_DELAY = 1000/FRAME_RATE; 

public void run()
      {
          
          long frameStart                  = 0;
            long frameCount             = 0;
            long totalElapsedTime       = 0;
            long elapsedTime             = 0;
            long reportedFramerate       = 0;
            
            long startTime;
                        
            // main game loop
            while(isRunning)
            {
                  frameStart = System.currentTimeMillis();
                  
                  // drawing to the double buffer
                  updateGame();
                  renderGame();
                  // drawing double buffer to panel's screen
                  renderScreen();
                  elapsedTime = System.currentTimeMillis()-frameStart;

                  try 
                  {
                        if(elapsedTime < Arkanoid.FRAME_DELAY)
                        {                              
                              Thread.sleep(Arkanoid.FRAME_DELAY - elapsedTime);
                        }
                  }
                  catch (InterruptedException e) {}
                        
                  frameCount++;
                  totalElapsedTime+=(System.currentTimeMillis()-frameStart);
                  
                  if(totalElapsedTime > 1000)
                  {
                        fps = reportedFramerate = (long) ((double)frameCount/ (double)totalElapsedTime*1000.0);
                        frameCount = 0;
                        totalElapsedTime = 0;
                  }
                  
            }
      }


the run thread is stored in a jpanel class which gets added
to a jframe (test on 800x600, windowed).
according to infos i got from inet i tested the granularity of
win xp and came to the result of 10ms. therefore it sdould be possible to get nearly up to 1sec/ 10 ms fps.
but i only get 30fps.
rest of the program does nothing except drawing the fps doublebuffered to the panel.

who has stolen the rest of my fps ?

Are you giving Swing the (unwanted) chance to coalesce repaint calls? I.e. using repaint() rather than paintImmediately()? That might explain it.

Cheers,
Mikael Grev

ah, should have mentioned that:
im using active rendering and setIgnoreRepaint(true);

Maybe drawing needs the time - who knows?

It should be mentioned that this way of timing is BAD - really.
I would suggest to check every frame how long computation took and after this calculate how far charakters, animation etc. should have moved.
This is much better and also gives older PCs a chance…

lg Clemens

sure, but this idea will be added later. for now i want to know
why i do not get the frames which i expect. and like i mentioned before no drawing or calculation is done except displaying of the fps on a double buffer

Which image-type do you use for double-buffering?
How many fps do you get if you remove the sleep() call?

odd thing is, without sleep i get same results of max 32 fps.
the offscreen buffer is a bufferedimage, which should be harware accelerated.

Nononnonon - BufferedImage gets no hardware-accerlation at all.
Btw. why do you think it should be accerlated?

At every drawImage() call the whole image is copied from user-space to your graphic board and then painted. Painting itself is nearly 100% done with software loops.

For this tasks use VolatileImage but please read some tuts howto use it, strange results may appear if you don’t use it the right way!

Good luck and let me hear if it helped, lg Clemens

seems that i need to get some lessons.

as far as i am concerned 1.5 tries to accelerate every bufferedimage. i thought this would be a great deal cause vram stored images would boost up performance (especially when you think that image drawing is often main bottleneck).

i will try to use volatile images tonight, but it would scare me that normal double buffering with usual images would only bring 30fps on my pc …

BufferedImages cannot be accerlated even in 1.5 since they allow direkt acess to the image-data-array which therefor must be held in ram.

30fps with an 800x600 image. Well, 800x600 are I think about 5mb x 30 = 150mb so 150mb need to copied from ram to vram, there are converts between and so on…
BufferedImage were never designed for doublebuffering!

I would suggest to read the imaging tutorial, it should help a lot.

BufferedImages are accelerated pre-1.5 if created from createCompatibleImage from the GraphicsConfiguration route. They can have that acceleration and lose it if you CALL getRaster(). But if you don’t call it, there’s no threat of the data buffer being messed with. I promise you can accelerate BufferedImages. Rimscape runs with them completely :slight_smile:

Not for a back buffer though!

Reading from a BufferedImages will be accelerated once the image is cached in vram, however any writing too the image has to be done to the master copy (which is in main memory). This blit is done in software, also, the cached copy in vram becomes invalid.

If you have a back buffer, and most of the operations to it are hardware acceleratable you should be using VolatileImage not BufferedImage.

If the majority of your blits are not hardware accelerated, the reverse is true, having a VolatileImage back buffer may well slow down your app…

To summarise, 2 Simple rules :-

BufferedImages exist in main memory, and will be cached in VRAM (at the discretion of the VM, and subject to vram memory constraints).

VolatileImages always exist in vram (if vram is available).

ok. seems that my problem gets a shape and a united voice screams for a volatile image.
i already knew that my test-strategy of using a normal double-buffered image would not get best results, buit i didnt expect such bad ones.

my working day is slowly snaking to its end, tonight i will know more ;D

ok, after long time passing i now tried bufferstrategy. for a black screen with a circle drawn and bumping around i get a max on ~150 fps. and this seems to be limited with my lazy use of Thread.sleep().
thx for the discussion. :smiley:

Try instead of the Thread.sleep(x) try Thread.yield(), it will give you ALOT more FPS!

so do this:


try {
  Thread.yield();
}catch (Exception ex) {
}

DP

hmmm, but up to now i really pause my game, so i need sleep(time). if im not wrong yield has no argument …

Thread.yield() doesn’t take any parameters because it isn’t time based. All it does is give up the current execution slice to some other thread. I highly recommend that you go grab a copy of GAGETimer and use that to time your game. It should take care of most of the issues for you.