Page 1 of 1

Progress bar clipped image not pixel aligned correctly

Posted: Fri Jun 18, 2010 04:27
by Charles
Hi,

When using the progress bar and image is being clipped, the width/height value does not get aligned to pixels correctly before being rendered.

This results in what is shown in the image at bottom left corner.
Image
Parts of image end up different than what they should be and can see it changing when progress bar is being updated.

Fixes:
These have both been tested.

Fix 1 is more of a quick hack to help identify cause of problem before looking deeper into it.
Fix 2 is what i am currently using, seems more elegant, although i do not know what side effects it might have if any.

Fix 1:
Within File: cegui/src/WindowRendererSets/Falagard/FalProgressBar.cpp Function: FalagardProgressBar::render

The is first thing i tried when trying to figure out the cause of the problem. Changes the height and width to integer.

Original code:

Code: Select all

        if (d_vertical)
        {
            float height = progressClipper.getHeight() * w->getProgress();

            if (d_reversed)
            {
                progressClipper.setHeight(height);
            }
            else
            {
                progressClipper.d_top = progressClipper.d_bottom - height;
            }
        }
        else
        {
            float width = progressClipper.getWidth() * w->getProgress();

            if (d_reversed)
            {
                progressClipper.d_left = progressClipper.d_right - width;
            }
            else
            {
                progressClipper.setWidth(width);
            }
        }


Changed code:

Code: Select all

        if (d_vertical)
        {
            int height = static_cast<int>(progressClipper.getHeight() * w->getProgress());

            if (d_reversed)
            {
                progressClipper.setHeight(static_cast<float>(height));
            }
            else
            {
                progressClipper.d_top = progressClipper.d_bottom - height;
            }
        }
        else
        {
            int width = static_cast<int>(progressClipper.getWidth() * w->getProgress());

            if (d_reversed)
            {
                progressClipper.d_left = progressClipper.d_right - width;
            }
            else
            {
                progressClipper.setWidth(static_cast<float>(width));
            }
        }


Fix 2:
Within File: cegui/src/CEGUIImageset.cpp Function: Imageset::draw

Seems most of time final_rect is already aligned to pixels so would be why this is not happening with other images.
So tex_rect would end up being created using a final_rect that is not pixel aligned for when progress bar is drawn
with the clipping.

Original code:

Code: Select all

// calculate final, clipped, texture co-ordinates
Rect  tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
   (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
   (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
   (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);
   
final_rect.d_left   = PixelAligned(final_rect.d_left);
final_rect.d_right   = PixelAligned(final_rect.d_right);
final_rect.d_top   = PixelAligned(final_rect.d_top);
final_rect.d_bottom   = PixelAligned(final_rect.d_bottom);


Changed code:

Code: Select all

// calculate final, clipped, texture co-ordinates
final_rect.d_left   = PixelAligned(final_rect.d_left);
final_rect.d_right   = PixelAligned(final_rect.d_right);
final_rect.d_top   = PixelAligned(final_rect.d_top);
final_rect.d_bottom   = PixelAligned(final_rect.d_bottom);

Rect  tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
   (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
   (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
   (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);

Re: Progress bar clipped image not pixel aligned correctly

Posted: Mon Jun 21, 2010 08:48
by CrazyEddie
Firstly, I have to say that I've not been aware of any issues with the progress bar, and secondly, that I've not looked to see if I can reproduce this issue as of yet. Is the issue easily reproduced with the imagesets / looknfeel that come with CEGUI? If not could you provide some files that demonstrate the issue clearly - just as an aide in confirming this as an issue.

Code changes must be in the form of unified diffs, and preferably against a subversion checkout that includes revision numbers. Or alternatively your submission should indicate the version of the code. Also, this should be submitted to the mantis tracker (http://mantis.cegui.org.uk), because otherwise it will get lost and forgotten about. See here for more info about such things: http://www.cegui.org.uk/docs/current/devel.html

[Edit]
I will add ticket with a link back here for this issue, and look into it when I get a chance. If you could provide some info as regards to reproducing it in the mean time, that would be great.

Thanks,

CE

Re: Progress bar clipped image not pixel aligned correctly

Posted: Mon Jun 21, 2010 13:31
by Charles
Thanks for the reply and putting it on the tracker,

At the time i thought it was best to post it here on the forum, have taken note about the code changes and mantis tracker etc.

I have tried it with the WindowsLook and TaharezLook. Did not notice anything with the WindowsLook but i did with the TaharezLook, was using WindowsLook/ProgressBar and TaharezLook/ProgressBar.

So it is possible to reproduce using TaharezLook but i have put together some files that demonstrate it clearly with the image / looknfeel i was using.

progressbar.png
Image

progressbar.scheme

Code: Select all

<?xml version="1.0" ?>
<GUIScheme Name="ProgressBarSkin">
   <Imageset Filename="progressbar.imageset" />
   <LookNFeel Filename="progressbar.looknfeel" />
   <WindowRendererSet Filename="CEGUIFalagardWRBase" />
   <FalagardMapping WindowType="ProgressBar/Vertical" TargetType="CEGUI/ProgressBar" Renderer="Falagard/ProgressBar" LookNFeel="ProgressBar/Vertical" />
</GUIScheme>


progressbar.looknfeel

Code: Select all

<?xml version="1.0" ?>
<Falagard>
   <WidgetLook name="ProgressBar/Vertical">
      <Property name="VerticalProgress" value="True" />
      <PropertyDefinition name="Image" initialValue="" redrawOnWrite="true" />
      <NamedArea name="ProgressArea">
         <Area>
            <Dim type="LeftEdge" ><AbsoluteDim value="0" /></Dim>
            <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
            <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
            <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
         </Area>
      </NamedArea>
      <ImagerySection name="progress">
         <ImageryComponent>
            <Area>
               <Dim type="LeftEdge" ><UnifiedDim scale="0" type="LeftEdge" /></Dim>
               <Dim type="TopEdge" ><AbsoluteDim value="0" /></Dim>
               <Dim type="Width" ><UnifiedDim scale="1" type="Width" /></Dim>
               <Dim type="Height" ><UnifiedDim scale="1" type="Height" /></Dim>
            </Area>
            <ImageProperty name="Image" />
         </ImageryComponent>
      </ImagerySection>
      <StateImagery name="Enabled" />
      <StateImagery name="EnabledProgress">
         <Layer>
            <Section section="progress" />
         </Layer>
        </StateImagery>
        <StateImagery name="Disabled" />
        <StateImagery name="DisabledProgress" />
    </WidgetLook>
</Falagard>


progressbar.layout

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<GUILayout>
   <Window Type="ProgressBar/Vertical" Name="ProgressBar">
      <Property Name="Image" Value="set:progressbar image:vertical" />
      <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{0,42},{0,64}}" />
   </Window>
</GUILayout>


Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<Imageset Name="progressbar" Imagefile="progressbar.png" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true" >
   <Image Name="vertical" XPos="0" YPos="0" Width="42" Height="64" />
</Imageset>


Also i am using the OpenGL renderer, i have not tried with any other therefore i do not know if this makes any difference and
the progress bar is being updated within the main loop using:

Code: Select all

setProgress(current / static_cast<float>(maximum));

Re: Progress bar clipped image not pixel aligned correctly

Posted: Mon Jun 21, 2010 13:53
by CrazyEddie
OK, cool. Thanks for the info and the data files. I will have a look soon - likely in a week to ten days, as I'm going AWOL for a bit ;)

CE.

Re: Progress bar clipped image not pixel aligned correctly

Posted: Mon Aug 02, 2010 09:31
by CrazyEddie
Just a note to say that I (finally) got around to testing this, and the issue is now fixed in SVN branches/v0-7 r2576.

Thanks again, and sorry for the quite slow progress!

CE.