User avatar
Scherub
Topic Author
Posts: 141
Joined: 06 May 2014, 20:53
Contact:

'Texture Atlas' and uniform scaling

23 Nov 2015, 02:06

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? :)
 
User avatar
sfernandez
Site Admin
Posts: 1911
Joined: 22 Dec 2011, 19:20

Re: 'Texture Atlas' and uniform scaling

23 Nov 2015, 13:46

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}"/> 
 
User avatar
Scherub
Topic Author
Posts: 141
Joined: 06 May 2014, 20:53
Contact:

Re: 'Texture Atlas' and uniform scaling

23 Nov 2015, 14:20

Ah, very cool. Your custom ImageViewbox works great. Thank you very much! :)

Who is online

Users browsing this forum: No registered users and 2 guests