Page 1 of 1

'Texture Atlas' and uniform scaling

Posted: 23 Nov 2015, 02:06
by Scherub
Up until now I used separate images for my project and all the image scaling worked as expected. Since I'm nearing completion I wanted to switch to a kind of 'texture atlas' as suggested by NoesisGUI on this page.

I starting exporting a sprite sheet with the also suggested Texture Packer. Unfortunaly I have trouble scaling them uniformly in WPF/NoesisGUI. I think I tried every possible combination of the ImageBrush's Stretch mode and the Rectangle's Stretch mode but none works the way I hoped it would.

I think it would work if the sprites would have a sqared size. But that would also waste lots of space on the sprite sheet.

So what's the suggested solution to this? :)

Re: 'Texture Atlas' and uniform scaling

Posted: 23 Nov 2015, 13:46
by sfernandez
I guess that stretch is not working because you have to set the Width and Height in your Rectangle to preserve the aspect ratio of the image. In that case you can wrap the Rectangle with a Viewbox that stretches as you want.
<Viewbox>
  <Rectangle Fill="{StaticResource imageFromAtlas}" Width="64" Height="48"/>
</Viewbox>
You can improve this by creating your own Viewbox class, that provides an Image property where you can set the image brush resource, and that automatically obtains image size:
public class ImageViewbox: Viewbox
{
    public static DependencyProperty ImageBrushProperty = DependencyProperty.Register(
        "ImageBrush", typeof(ImageBrush), typeof(ImageViewbox),
        new PropertyMetadata(null, OnImageBrushChanged));

    static void OnImageBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ImageViewbox vb = d as ImageViewbox;
        if (vb != null)
        {
            Rectangle rect = vb.Child as Rectangle;
            if (rect == null)
            {
                rect = new Rectangle();
            }

            ImageBrush brush = e.NewValue as ImageBrush;
            rect.Fill = brush;

            if (brush != null)
            {
                // We can extract the image size from the ImageBrush.Viewbox
                if (brush.ViewboxUnits == BrushMappingMode.Absolute)
                {
                    rect.Width = brush.Viewbox.Width;
                    rect.Height = brush.Viewbox.Height;
                }
                else
                {
                    rect.Width = brush.ImageSource.Width * brush.Viewbox.Width;
                    rect.Height = brush.ImageSource.Height * brush.Viewbox.Height;
                }
            }
            else
            {
                rect.Width = rect.Height = 0.0f;
            }

            vb.Child = rect;
        }
    }
} 
<ImageViewbox Stretch="Uniform" ImageBrush="{StaticResource imageFromAtlas}"/> 

Re: 'Texture Atlas' and uniform scaling

Posted: 23 Nov 2015, 14:20
by Scherub
Ah, very cool. Your custom ImageViewbox works great. Thank you very much! :)