midp 1.0 back-buffering

I recenetly started coding j2me midp 1.0,
i added some basic animation and keyboard control but the animation looks choppy, this is probably because the lack of back buffering in my app.

can someone please post a simple example of how to implement back buffering in midp 1.0 ?
(i’m talking about the process of drawing into a virtual screen buffer and then flipping into the real screen with vertical sync)
thanks in advance :slight_smile:

Edit: i managed to do the back buffering, i’m simply writing to an Image i created (in the same size of the device actual screen size) and whenever i want to “flip”, i just do g.drawImage(backBufferImage,0,0,g.TOP|g.LEFT);

but the animation is STILL choppy ;(
is there a way i can wait for vert sync?

Most phones implement double buffering themselves. The Canvas class has a isDoubleBuffered method you can query. But on some devices (T610 I’m looking at you), even though they say they are double buffered they still act wierd.

Anyway, here is a pretty generic implementation that can handle both types of devices:


class MyCanvas extends Canvas {
  private Image backBuffer;
  private Graphics backBufferGraphics;

  public MyCanvas() {
    if (!isDoubleBuffered()) {
      // note: on some phones getHeight() gives wrong results, so watch out
      backBuffer = Image.createImage(getWidth(),getHeight());
      backBufferGraphics = backBuffer.getGraphics();
    }
    // ....
  }

  public void paint(Grapphics g) {
    Graphics original;
    if (backBuffer != null) {
      original = g;
      g = backBufferGraphics;
    }
    // regular paint code using g
    if (original != null) {
      original.drawImage(backBuffer,0,0,Graphics.TOP|Graphics.LEFT);
    }
  }
}

shmoove

thanks alot shmoove :slight_smile:
after posting my question i found a similar solution, but the animation still looks choppy :frowning:
description of what my app does:
(i didn’t know that some devices are auto-double-buffered so i’ll add code to handle that as well now - thanks :slight_smile: )

first i clear the virtual buffer image.
I draw some image to the virtual buffer image.
I draw a rectangle and in it some text to the virtual buffer image.
i draw the virtual buffer image into the real device screen.

the rectangle that has text in it is controlled with the keys of the mobile.

for some reason, the rectangle+text leaves some sort of a trail, and looks VERY choppy when running the app on my device (nokia 3100).

any idea of what might be the cause?

here is my code:

public void paint(Graphics g) {          
      
      if (!bInitedGraphicsSize)       
            initBackBuffer(g);                 
      
    // clear the screen:
    backBufferGraphics.setColor(0xffffff);
     backBufferGraphics.fillRect(CORNER_X, CORNER_Y, DISP_WIDTH, DISP_HEIGHT);
    
    // draw text
     Font dFont = backBufferGraphics.getFont();
     int fontH = dFont.getHeight();
    int fontW = dFont.stringWidth("Devour!");
    
      backBufferGraphics.setColor(0xff0000);
      backBufferGraphics.fillRect((DISP_WIDTH-fontW)/2 - 1 + iTextPosX, (DISP_HEIGHT-fontH)/2 + iTextPosY,
                   fontW + 2, fontH);           
      backBufferGraphics.setColor(0x00ff00);      
      backBufferGraphics.setFont(dFont);
      backBufferGraphics.drawString("Devour!", (DISP_WIDTH-fontW)/2 + iTextPosX, (DISP_HEIGHT-fontH)/2 + iTextPosY,
                   g.TOP|g.LEFT);

        // draw the player
    player.paint(backBufferGraphics);
      
      // flip the back buffer onto the real device screen
      g.drawImage(backBufferImage, 0,0, g.TOP|g.LEFT);      
      
  }

Edit:
ok, i changed my code (now it’s more similar to yours, and handles both cases)
i tested and found that the device i’m testing (nokia 3100) has double buffering… :confused:
prehaps the reason is different.

I have solved this by not redrawing the entire back buffer every time. I draw the front buffer into the back buffer with the offset and then only draw the edges of the back buffer. Once I have the edges drawn, I swap front and back buffers. This is only useful for the background, but drawing the dynamic items directly on the screen after bliting of the background has worked well for me. My back buffers are typically 20 pixels larger than screen size and I scroll them smoothly on the screen and only update/swap the back buffer on 20 pixel boundaries.

This doesn’t work on a Samsung phone I have, but I do have a work around which I posted in another topic. Otherwise, it has worked well for me on every other phone.

Wood

Aaahhh. An older Series 40 phone. In that case I think I have some bad news for you. It’s a hardware issue. They use cheapo screens and if you move high-contrast fast enough they always leave a trail (the pixels just seem to hang around for a while longer). The only possible workaround is to try to use colors that don’t have high contrasts between them in order to “hide” the ghosting effect.

shmoove

shmoove:
Thanks, i’ll be aware from now on to this and tell my artist to create the art accordingly… :slight_smile:
i’m not too annoyed by this hardware issue because i just played might & magic in my nokia 3100 and it was so cool, so apperently some really cool things can still be done :slight_smile:

wood:
i’m not sure i understood your answer ;(

What does your solution solve?
it prevents the trail of fast moving sprites? it is your implementation of double buffering?

didn’t quite understand parts like
“I draw the front buffer into the back buffer with the offset and then only draw the edges of the back buffer.”

[quote] wood:
i’m not sure i understood your answer ;(
[/quote]
Performance Enhancement 1:
If you are having performance problems, the first thing you do is start drawing offscreen and bliting the offscreen image to the screen on update. That’s what you are already doing.

Performance Enhancement 2:
If you are still having problems then you have to look at where else you can cut out drawing. One of my solutions is to draw one offscreen image with another being offset in the direction the screen is moving, then only update the edges. Instead of redrawing the entire offscreen image everytime three is a change.

Performance Enhancement 3:
The next step is to keep a larger than screen set of offscreen images and offset the offscreen blit until you reach and edge, then do the redrawing of the edges in #2 above and reset the offset.

I have yet to launch a game where I have not had to do all three of these steps for at least one of the devices and now I just do all 3 for all devices as it makes the game faster on all the devices.

Wood

thanks :slight_smile: