Pergunta

I have converted my C# game from OpenTK (OpenGL) to SharpDX (DirectX) and have it up and running from Visual Studio 2010. I also have it up and running from Visual Studio 11 in Metro, in the Windows 8 Developer Preview. However, the Metro build is still lacking textures, so my polygons are simply colored right now. The problem is that the methods used to load images are absent in the Metro DLLs. These methods are all missing from the Texture2D class (inherited from the Resource class) in Windows Store App:

SharpDX.Direct3D11.Resource.FromStream
SharpDX.Direct3D11.Resource.FromFile
SharpDX.Direct3D11.Resource.FromMemory

Does anyone know if these will eventually be implemented in Metro? Or is there an alternate approach I could be using? Please keep in mind that I never knew a thing about DirectX or SharpDX before this, so I'm still very wet behind the ears with all this.

Finding any kind of help or information for SharpDX is not easy, which is a shame, because it seems to be a great solution for 3D in Metro using C#.

Foi útil?

Solução 3

Good news! Alexandre Mutel, the author of SharpDX, let me know that Microsoft removed the "helper methods" from Direct3D11. It wasn't an omission by SharpDX. And he also pointed me in the right direction; to use WIC to load my textures. I found sample code here:

http://crazylights.googlecode.com/svn/CLReach/win8/SDX_CLGC/clgc.cs

I just needed two of the methods: LoadBitmap() and CreateTex2DFromBitmap(). I had to change the "R8G8B8A8_UNorm_SRgb" to "R8G8B8A8_UNorm", but ultimately I got it working. And now my game now looks fabulous in Metro with all it's textures in place! :)

Outras dicas

I'm not sure I've clearly understood your question, but in SharpDX samples I've found class 'TextureLoader' that has two methods: 'LoadBitmap' and 'CreateTexture2DFromBitmap'. Look, you can use this function to load BitmapSource from .bmp, .png, .jpg files:

    public static BitmapSource LoadBitmap(ImagingFactory2 factory, string filename)
    {
        var bitmapDecoder = new SharpDX.WIC.BitmapDecoder(
            factory,
            filename,
            SharpDX.WIC.DecodeOptions.CacheOnDemand
            );

        var result = new SharpDX.WIC.FormatConverter(factory);

        result.Initialize(
            bitmapDecoder.GetFrame(0),
            SharpDX.WIC.PixelFormat.Format32bppPRGBA,
            SharpDX.WIC.BitmapDitherType.None, 
            null,
            0.0, 
            SharpDX.WIC.BitmapPaletteType.Custom);

        return result;
    }

To get Texture2D from BitmapSource you can use this:

    public static Texture2D CreateTexture2DFromBitmap(Device device, BitmapSource bitmapSource)
    {
        // Allocate DataStream to receive the WIC image pixels
        int stride = bitmapSource.Size.Width * 4;
        using (var buffer = new SharpDX.DataStream(bitmapSource.Size.Height * stride, true, true))
        {
            // Copy the content of the WIC to the buffer
            bitmapSource.CopyPixels(stride, buffer);
            return new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
            {
                Width = bitmapSource.Size.Width,
                Height = bitmapSource.Size.Height,
                ArraySize = 1,
                BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
                Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
                CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
                Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm,
                MipLevels = 1,
                OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
                SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
            }, new SharpDX.DataRectangle(buffer.DataPointer, stride));
        }
    }

and in order to make it easier, I've created this function:

        public static Texture2D LoadFromFile(Device device, ImagingFactory2 factory, string fileName)
        {
            var bs = LoadBitmap(factory, fileName);
            var texture = CreateTexture2DFromBitmap(device, bs);
            return texture;
        }

You do not need to use WIC to load textures in Metro, you can also create them from a BitmapImage (it works in Metro and is less complicated):

public static Texture2D FromImage(BitmapImage image, GraphicsDevice device)
{
    WriteableBitmap bitmap = new WriteableBitmap(image);

    return FromImageData(bitmap.Pixels, bitmap.PixelWidth, 
                            bitmap.PixelHeight, device);
}

public static Texture2D FromImageData(int[] data, int width, int height, GraphicsDevice device)
{
    Texture2D texture = Texture2D.New(device, width, height,
                                    PixelFormat.B8G8R8A8.UNorm);

    texture.SetData<int>(data);

    return texture;
}

See my answer here: SharpDX load a texture in Windows Phone 8

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top