Double buffer help

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Martin

    #1

    Double buffer help

    I'm a newbie to Java and have today completed my first Java applet.

    It's a panorama viewer which i intend to use on my website instead of
    Apple's Quicktime Virtual Reality (QTVR) format.
    I've used the QTVR format for a while but think that i'd get more visitors
    with a Java applet - too few visitors have the QTVR browser plugin installed
    and with the Quicktime installation now a massive 34.8MB i feel i'm losing
    visitors because it's just too much time and hassle for an 'average' visitor
    to install.

    Anyway back to the point of my post....

    My panorama viewer applet suffers from flickering graphics as it pans around
    a panoramic image - the faster it pans, the worse the flicker.
    (Image quality is acceptable with slow pan speeds however).

    Here's the Paint method that i originally wrote:

    public void paint(Graphics g)
    {
    // draw main image
    g.drawImage(vrI mage,panPositio n,0,this);
    // pad main image end to create 360 degree panoramic effect
    if (panPosition<(i mageWidth-displayWidth))
    g.drawImage(vrI mage,panPositio n+imageWidth,0, this);
    if (panPosition>0) g.drawImage(vrI mage,panPositio n-imageWidth,0,th is);
    }

    vrImage is a JPG panoramic image with a height of 104 pixels, width varies
    but averages about 1050 pixels.
    panPosition is an integer that stores where in vrImage's width the viewer is
    currently viewing.
    imageWidth is the width of vrImage.
    displayWidth is the applet width as determined within the applet tag of my
    HTML page - currently it's 140 pixels.

    I have a timer thread which advances the panning either way horizontally.
    A mouseEntered event starts the timer, and the timer delay and pan direction
    are determined by the position of the mouse over my image - it pans faster
    as you move the mouse towards either left of right edge of the image.
    A mouseExited event stops the timer.

    All is acceptable (just!) if the panorama pans slowly, but as it pans faster
    the image flickers and it looks rather unprofessional.

    I've spent ages searching for a solution - use buffering, write all graphics
    to a single image and then draw the single image to the screen.
    Unfortunately all the tutorials and code examples i've found have been too
    complex for me.

    The best i have done is to rewrite my Paint method:

    public void paint(Graphics g)
    {
    Image buffer=createIm age(displayWidt h,displayHeight );
    Graphics bufferG=buffer. getGraphics();
    bufferG.drawIma ge(vrImage,panP osition,0,this) ;
    if (panPosition<(i mageWidth-displayWidth))
    bufferG.drawIma ge(vrImage,panP osition+imageWi dth,0,this);
    if (panPosition>0)
    bufferG.drawIma ge(vrImage,panP osition-imageWidth,0,th is);
    // draw buffer to screen
    g.drawImage(buf fer,0,0,this);
    }

    The result is worse than my original (unbuffered) code!
    The image degrades with just about any pan movement whatsoever, and with
    fast panning the image just disappears behind the flickering.

    Can anyone suggest what i can do to improve the quality of the panoramic
    image?
    Please remember this is my first project so my knowledge is very limited.

    Thanks a lot for any help.

    Martin.

    --
    No replies to this email address please.


  • Martin

    #2
    Re: Double buffer help


    "Martin" <zedolf@o2.co.u k> wrote in message
    news:Eemdne5N39 tdvrLZnZ2dnUVZ8 qGdnZ2d@pipex.n et...[color=blue]
    > I'm a newbie to Java and have today completed my first Java applet.
    >
    > It's a panorama viewer which i intend to use on my website instead of
    > Apple's Quicktime Virtual Reality (QTVR) format.
    > I've used the QTVR format for a while but think that i'd get more visitors
    > with a Java applet - too few visitors have the QTVR browser plugin
    > installed and with the Quicktime installation now a massive 34.8MB i feel
    > i'm losing visitors because it's just too much time and hassle for an
    > 'average' visitor to install.
    >
    > Anyway back to the point of my post....
    >
    > My panorama viewer applet suffers from flickering graphics as it pans
    > around a panoramic image - the faster it pans, the worse the flicker.
    > (Image quality is acceptable with slow pan speeds however).
    >
    > Here's the Paint method that i originally wrote:
    >
    > public void paint(Graphics g)
    > {
    > // draw main image
    > g.drawImage(vrI mage,panPositio n,0,this);
    > // pad main image end to create 360 degree panoramic effect
    > if (panPosition<(i mageWidth-displayWidth))
    > g.drawImage(vrI mage,panPositio n+imageWidth,0, this);
    > if (panPosition>0) g.drawImage(vrI mage,panPositio n-imageWidth,0,th is);
    > }
    >
    > vrImage is a JPG panoramic image with a height of 104 pixels, width varies
    > but averages about 1050 pixels.
    > panPosition is an integer that stores where in vrImage's width the viewer
    > is currently viewing.
    > imageWidth is the width of vrImage.
    > displayWidth is the applet width as determined within the applet tag of my
    > HTML page - currently it's 140 pixels.
    >
    > I have a timer thread which advances the panning either way horizontally.
    > A mouseEntered event starts the timer, and the timer delay and pan
    > direction are determined by the position of the mouse over my image - it
    > pans faster as you move the mouse towards either left of right edge of the
    > image.
    > A mouseExited event stops the timer.
    >
    > All is acceptable (just!) if the panorama pans slowly, but as it pans
    > faster the image flickers and it looks rather unprofessional.
    >
    > I've spent ages searching for a solution - use buffering, write all
    > graphics to a single image and then draw the single image to the screen.
    > Unfortunately all the tutorials and code examples i've found have been too
    > complex for me.
    >
    > The best i have done is to rewrite my Paint method:
    >
    > public void paint(Graphics g)
    > {
    > Image buffer=createIm age(displayWidt h,displayHeight );
    > Graphics bufferG=buffer. getGraphics();
    > bufferG.drawIma ge(vrImage,panP osition,0,this) ;
    > if (panPosition<(i mageWidth-displayWidth))
    > bufferG.drawIma ge(vrImage,panP osition+imageWi dth,0,this);
    > if (panPosition>0)
    > bufferG.drawIma ge(vrImage,panP osition-imageWidth,0,th is);
    > // draw buffer to screen
    > g.drawImage(buf fer,0,0,this);
    > }
    >
    > The result is worse than my original (unbuffered) code!
    > The image degrades with just about any pan movement whatsoever, and with
    > fast panning the image just disappears behind the flickering.
    >
    > Can anyone suggest what i can do to improve the quality of the panoramic
    > image?
    > Please remember this is my first project so my knowledge is very limited.
    >
    > Thanks a lot for any help.
    >
    > Martin.
    >
    > --
    > No replies to this email address please.
    >
    >[/color]

    For anyone interested i've created a temporary webpage where you can see
    both my original code and the supposedly buffered code in action!



    Martin.


    Comment

    • Ian Shef

      #3
      Re: Double buffer help

      "Martin" <zedolf@o2.co.u k> wrote in
      news:v72dnULQsr w6WLLZnZ2dnUVZ8 s-dnZ2d@pipex.net :
      [color=blue]
      >
      > "Martin" <zedolf@o2.co.u k> wrote in message
      > news:Eemdne5N39 tdvrLZnZ2dnUVZ8 qGdnZ2d@pipex.n et...[color=green]
      >> I'm a newbie to Java and have today completed my first Java applet.
      >>[/color][/color]
      <snip>[color=blue][color=green]
      >>
      >> My panorama viewer applet suffers from flickering graphics as it pans
      >> around a panoramic image - the faster it pans, the worse the flicker.
      >> (Image quality is acceptable with slow pan speeds however).
      >>[/color][/color]
      <snip>

      You don't say what component your Paint() method is in.
      You don't say how you are causing the image to be redrawn.

      I will guess that you are calling repaint(...). If I recall correctly,
      repaint actually causes update(...) to be called. The default action for
      update is to clear the drawing area, and then call paint(...).

      You may need to override update to call paint directly.

      .... or I may be completely off base, reasoning from insufficient information.
      Source code would be nice.


      --
      Ian Shef 805/F6 * These are my personal opinions
      Raytheon Company * and not those of my employer.
      PO Box 11337 *
      Tucson, AZ 85734-1337 *

      Comment

      • Martin

        #4
        Re: Double buffer help


        "Ian Shef" <invalid@avoidi ng.spam> wrote in message
        news:Xns979A7C7 A78E98vaj4088ia nshef@138.126.2 54.210...[color=blue]
        > "Martin" <zedolf@o2.co.u k> wrote in
        > news:v72dnULQsr w6WLLZnZ2dnUVZ8 s-dnZ2d@pipex.net :
        >[color=green]
        >>
        >> "Martin" <zedolf@o2.co.u k> wrote in message
        >> news:Eemdne5N39 tdvrLZnZ2dnUVZ8 qGdnZ2d@pipex.n et...[color=darkred]
        >>> I'm a newbie to Java and have today completed my first Java applet.
        >>>[/color][/color]
        > <snip>[color=green][color=darkred]
        >>>
        >>> My panorama viewer applet suffers from flickering graphics as it pans
        >>> around a panoramic image - the faster it pans, the worse the flicker.
        >>> (Image quality is acceptable with slow pan speeds however).
        >>>[/color][/color]
        > <snip>
        >
        > You don't say what component your Paint() method is in.
        > You don't say how you are causing the image to be redrawn.
        >
        > I will guess that you are calling repaint(...). If I recall correctly,
        > repaint actually causes update(...) to be called. The default action for
        > update is to clear the drawing area, and then call paint(...).
        >
        > You may need to override update to call paint directly.
        >
        > ... or I may be completely off base, reasoning from insufficient
        > information.
        > Source code would be nice.
        >
        >
        > --
        > Ian Shef 805/F6 * These are my personal opinions
        > Raytheon Company * and not those of my employer.
        > PO Box 11337 *
        > Tucson, AZ 85734-1337 *[/color]


        Brilliant!

        Yep my timer thread was calling repaint().
        I had a quick Google and found an example of using the update() method.

        I simply duplicated the code from my paint() method in the update() method
        and gave that a try and it's perfect.
        The flicker has disappeared.

        I've updated the temporary webpage too - both the old (flickering) applet
        and the new improved applet can both be seen in action.


        Thanks a lot - very easy and quick for me to fix it once i was pointed in
        the right direction.

        Martin.


        Comment

        • Ian Shef

          #5
          Re: Double buffer help

          "Martin" <zedolf@o2.co.u k> wrote in news:c9adncRoxO lOOazZRVnyiA@pi pex.net:
          [color=blue]
          >
          > Brilliant![/color]

          No, but thanks.[color=blue]
          >
          > Yep my timer thread was calling repaint().
          > I had a quick Google and found an example of using the update() method.[/color]

          An excellent resource for painting issues is
          "Painting in AWT and Swing":

          http://java.sun.com/products/jfc/tsc...ing/index.html

          [color=blue]
          >
          > I simply duplicated the code from my paint() method in the update()
          > method and gave that a try and it's perfect.[/color]
          Nooooooooooooo !!

          You are setting yourself up for a maintenance and debug nightmare.
          Provide the code in only ONE place!
          Either:
          1) Locate the code in paint(), and have update() call paint(), OR
          2) Locate the code in update(), and have paint() call update(), OR
          3) Locate the code in a new method, and have both paint() and update(0
          call the new method.
          [color=blue]
          > The flicker has disappeared.[/color]

          Glad to hear it.[color=blue]
          >
          > I've updated the temporary webpage too - both the old (flickering)
          > applet and the new improved applet can both be seen in action.
          > http://www.warwound.dsl.pipex.com/applet/panViewer.htm[/color]

          Nice contrast between the two cases. Thanks, I rarely get to see such a
          visible result of my advice.[color=blue]
          >
          > Thanks a lot - very easy and quick for me to fix it once i was pointed
          > in the right direction.
          >
          > Martin.
          >
          >
          >[/color]
          Happy to have helped.
          -- Ian



          --
          Ian Shef 805/F6 * These are my personal opinions
          Raytheon Company * and not those of my employer.
          PO Box 11337 *
          Tucson, AZ 85734-1337 *

          Comment

          • Martin

            #6
            Re: Double buffer help


            "Ian Shef" <invalid@avoidi ng.spam> wrote in message
            news:Xns979C800 D25A1Bvaj4088ia nshef@138.126.2 54.210...[color=blue]
            > "Martin" <zedolf@o2.co.u k> wrote in news:c9adncRoxO lOOazZRVnyiA@pi pex.net:
            >[color=green]
            >>
            >> Brilliant![/color]
            >
            > No, but thanks.[color=green]
            >>
            >> Yep my timer thread was calling repaint().
            >> I had a quick Google and found an example of using the update() method.[/color]
            >
            > An excellent resource for painting issues is
            > "Painting in AWT and Swing":
            >
            > http://java.sun.com/products/jfc/tsc...ing/index.html
            >
            >[color=green]
            >>
            >> I simply duplicated the code from my paint() method in the update()
            >> method and gave that a try and it's perfect.[/color]
            > Nooooooooooooo !!
            >
            > You are setting yourself up for a maintenance and debug nightmare.
            > Provide the code in only ONE place!
            > Either:
            > 1) Locate the code in paint(), and have update() call paint(), OR
            > 2) Locate the code in update(), and have paint() call update(), OR
            > 3) Locate the code in a new method, and have both paint() and update(0
            > call the new method.
            >[color=green]
            >> The flicker has disappeared.[/color]
            >
            > Glad to hear it.[color=green]
            >>
            >> I've updated the temporary webpage too - both the old (flickering)
            >> applet and the new improved applet can both be seen in action.
            >> http://www.warwound.dsl.pipex.com/applet/panViewer.htm[/color]
            >
            > Nice contrast between the two cases. Thanks, I rarely get to see such a
            > visible result of my advice.[color=green]
            >>
            >> Thanks a lot - very easy and quick for me to fix it once i was pointed
            >> in the right direction.
            >>
            >> Martin.
            >>
            >>
            >>[/color]
            > Happy to have helped.
            > -- Ian
            >
            >
            >
            > --
            > Ian Shef 805/F6 * These are my personal opinions
            > Raytheon Company * and not those of my employer.
            > PO Box 11337 *
            > Tucson, AZ 85734-1337 *[/color]

            Thanks for the advice about duplicating the drawing code.

            I've rewritten my applet and created a new method which i've called
            displayRedraw() and moved the code to that method.
            Then both paint() and update() methods merely call my new displayRedraw()
            method and all works as before - even makes the compiled class file a very
            little bit smaller too.

            I'll take a look at the "Painting in AWT and Swing" link later when i have
            more time.

            Thanks again.

            Martin.


            Comment

            Working...