removing flicker from JPCT applet with AWT graphics

Started by dmouse, August 14, 2008, 06:06:49 PM

Previous topic - Next topic

dmouse

Hi all,

I was wondering if anyone knows how to remove the flickering when using standard Java AWT methods for displaying images and text (ie g.drawImage and drawString ) on top of a JPCT FrameBuffer software  rendered 3d scene. The usual double buffering approach does not seem to work, the 3D scene renders smoothly but any text/graphics drawn on top flicker very badly. Am I perhaps missing something?

Does anyone know how to remove this flickering?

Thanks in advance, for any help/advice that anyone can offer.


EgonOlsen

Draw into the rendered image instead. You can get the graphics context from the framebuffer. This won't work in Java 1.1 though...

dmouse

Egon,

Thanks you for your nearly instantaneous reply!

OK, using "buffer.getGraphics().drawString (" display text here ",200,200);" works very well, the flickering is gone.

Is there a solution that will work for 1.1 compatible applets, as this is essential for me?

Thanks again.

EgonOlsen

The problem with 1.1 is, that it has to use MemoryImageSource, which doesn't provide a graphics context. If the text/image is static, use textures instead and blit those. If it isn't, you can draw the rendered image into another one, draw your text/images onto that and draw the whole bunch to screen. That will be slower of course, which is why i would limit it to 1.1. and use another pipeline for higher versions.
You can also access the pixels-array directly, but i doubt that this will be very helpful in this case.

fireside

#4
As long as we're on this topic.  I can't seem to set the font when I get the graphics context from the framebuffer for some reason.  It just gets ignored.  The same code works when I use g, but then I get flicker.  I can paint a string with graphics from framebuffer, but only in one type of font.  I'm compiling for 1.2.
click here->Fireside 7 Games<-

EgonOlsen

I guess that Graphics should be Graphics...i don't see why one should ignore the font while the other doesn't. All i'm doing is returning the Graphics from the BufferedImage that holds the pixel data. Nothing special, no magic involved... ???

fireside

Here's a screen shot:


Here's the code with just switching the commented lines:

        buffer.clear(java.awt.Color.getHSBColor(-100, -100, 130));
        if(lives > 1)buffer.blit(mLife, 0, 0,0,0,16,50,true);       
        if(lives > 2)buffer.blit(mLife, 0, 0,32,0,16,50,true);
        if(hasCheese)buffer.blit(cheese, 0, 0,440,0,32,32,true);       
         world.renderScene(this.buffer);
        world.draw(this.buffer);
        buffer.update();       
        buffer.display(g);
//        if(win){buffer.getGraphics().setFont(myFont);g.drawString("Level Complete", 100, 175);}
        if(win){g.setFont(myFont);g.drawString("Level Complete", 100, 175);} 
click here->Fireside 7 Games<-

EgonOlsen

You are setting the font on the buffer's Graphics instance, but are rendering it into the screen's one. That can't work...

fireside

Not sure what you mean.  I had it above the world.renderScene(), and it did the same thing. 
click here->Fireside 7 Games<-

EgonOlsen

I mean this:

if(win){buffer.getGraphics().setFont(myFont);g.drawString("Level Complete", 100, 175);}

You are setting the font in another context than the screen's, but you are drawing to the screen.

It should be something like:

if(win){buffer.getGraphics().setFont(myFont);buffer.getGraphics().drawString("Level Complete", 100, 175);}

fireside

It's still little, but now it's white with this code:

world.renderScene(this.buffer);
world.draw(this.buffer);
if(true){buffer.getGraphics().setFont(myFont);buffer.getGraphics().drawString("Level Complete", 100, 175);}         
buffer.update();       
  buffer.display(g);


It seems to ignore the font.  I tried setting myFont to public, but it didn't help.
click here->Fireside 7 Games<-

EgonOlsen

#11
What can i say...it's just using normal Java2D methods on a normal Graphics-context of a normal BufferedImage. It should work fine. Maybe myFont is not what it is suspected to be?

fireside

I just copied it from some tutorial.  It's at the top with the other class variables.
public Font myFont = new Font("SansSerif", Font.BOLD, 30);

Well, maybe it will come clear later.  For now I'll just use graphics g and let it flicker if I have to change the font.
click here->Fireside 7 Games<-

dmouse

Hi,

I just wanted to say thank you to Egon again for his help with my original question in this thread.

I have decided to blit text and graphics over the the 3d scene, as this method will clearly work for 1.1 applets, 1.2+ applets and hardware accelerated applications, all with the same code. I initially thought this might be slower than g.drawString etc.., but isn't noticiably so, particularly with only a limited amount text being displayed (such as game menus and such).

Thanks again.

AGP

Fireside, I'm almost certain that if you do Graphics g = buffer.getGraphics(); g.setFont(myFont); g.drawString("My String."); it'll work like a charm. Try it out and let us know.