tags:

views:

277

answers:

3

The problem is that I can't select minimalization filter for Texture2D scaling. There is MinFilter

GraphicsDevice.SamplerStates[0].MinFilter

But it's not working. When I try to assign some filter it just changes back to the Linear.

Is there a way to implement my own filter or how to select one of the available?

+3  A: 

I read an article on Shawn Hargreaves' blog a while back that said, "SpriteBatch will automatically set what it needs for drawing in 2D...", which includes setting the MinFilter to Linear.

So, you could try what this article says to do and set your SpriteSortMode to Immediate. Then after your SpriteBatch.Begin call, you can set the MinFilter to whatever you want, and it should retain that setting when it draws the sprite.

Venesectrix
A: 

I have one answer to my own question and i think it will be better to post a new answer for readability.

    private Texture2D Scale(GraphicsDevice gd, Texture2D texture, float scale)
    {

        int sourceWidth = texture.Width;
        int sourceHeight = texture.Height;

        int destWidth = (int)(sourceWidth * scale);
        int destHeight = (int)(sourceHeight * scale);

        //convert texture into bitmap
        byte[] textureData = new byte[4 * sourceWidth * sourceHeight];
        texture.GetData<byte>(textureData);

        System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(sourceWidth, sourceHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, sourceWidth, sourceHeight), System.Drawing.Imaging.ImageLockMode.WriteOnly,
                       System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        IntPtr safePtr = bmpData.Scan0;
        System.Runtime.InteropServices.Marshal.Copy(textureData, 0, safePtr, textureData.Length);
        bmp.UnlockBits(bmpData);


        //output bitmap
        System.Drawing.Image outputImage = new System.Drawing.Bitmap(destWidth, destHeight, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        System.Drawing.Graphics grPhoto = System.Drawing.Graphics.FromImage(outputImage);
        grPhoto.InterpolationMode = (System.Drawing.Drawing2D.InterpolationMode)(interpolationMode);


        grPhoto.DrawImage((System.Drawing.Image)bmp, new System.Drawing.Rectangle(0, 0, destWidth, destHeight),
            new System.Drawing.Rectangle(0, 0, sourceWidth, sourceHeight), System.Drawing.GraphicsUnit.Pixel);

        grPhoto.Dispose();

        textureData = new byte[4 * sourceWidth * sourceHeight];

        MemoryStream ms = new MemoryStream();
        ((System.Drawing.Bitmap)outputImage).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
        ms.Seek(0, SeekOrigin.Begin);
        Texture2D result = Texture2D.FromFile(gd, ms);
        ms.Dispose();

        return result;
    }

This metod runs in about 20ms - 100ms depending on interpolation mode, maybe someone will find it usefull. Is there a way to optimize it? I dont need 32bit support but there seems to be no way to set it to 24. I found different sizing algorithms http://www.codeproject.com/KB/GDI-plus/imgresizoutperfgdiplus.aspx but they are slow.

Is there a way to implement these methods using speed of graphic card?

Kaminari
@Kaminari, regarding your question see my reply.
Pop Catalin
A: 

The best approach to minification is to create mipmaps for the textures as the hardware and the directx pipeline is optimized to use mipmaps in the best way possible depending on the final drawing size of the texture.

Here's a quote from MSDN on mipmaps

The most popular approach to minification is to create mipmaps for each texture. A mipmap is a pre-shrunk texture, normally half the size of the original. The mipmap itself then gets mipmapped, and this process continues until a 1x1 texture is created. This is the final mipmap for the texture. You can think of mipmaps as a chain, starting with the original texture and becoming smaller and smaller until the 1 texel texture is reached. When minification is needed, first the appropriate mipmapped texture is chosen, then that mipmap is applied to the object, with real-time texture filtering if needed. The default Texture processor for the Content Pipeline has an option to generate mipmaps automatically.

You can enable automatic mipmap generation using the content pipeline or Texture.GenerateMipMaps to generate mipmaps at runtime for a render target texture.

Pop Catalin
It's not a problem to create smaller image or speed of scale in `SpriteBatch` Draw method because it is very fast and gives superior results. Well, superior in ONLY one way - sharpness. I'm writing image/comic/manga reader and there have to be option to select INTERPOLATION method. Sometimes sharp it's not good. I think of writing some interpolation methods directly in C++ native code because it will be fast enough to scale images on the fly without lag.
Kaminari