在Windows应用商店应用中使用SharpDX加载纹理

时间:2012-03-07 13:07:54

标签: c# windows-8 windows-store-apps sharpdx direct3d11

我已经将我的C#游戏从OpenTK(OpenGL)转换为SharpDX(DirectX),并从Visual Studio 2010开始运行。我也在Windows 8开发人员预览版的Metro中使用Visual Studio 11运行它。然而,Metro构建仍然缺乏纹理,因此我的多边形现在只是着色。问题是Metro DLL中没有用于加载图像的方法。 Windows Store App中的Texture2D类(继承自Resource类)中缺少这些方法:

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

有谁知道这些最终是否会在Metro中实施?或者我可以使用另一种方法吗?请记住,在此之前,我从未对DirectX或SharpDX有所了解,所以我仍然非常浑浑噩噩。

为SharpDX寻找任何类型的帮助或信息并不容易,这是一种耻辱,因为它似乎是使用C#在Metro中使用3D的绝佳解决方案。

3 个答案:

答案 0 :(得分:6)

我不确定我是否清楚地理解了您的问题,但在SharpDX示例中,我发现类'TextureLoader'有两种方法:'LoadBitmap'和'CreateTexture2DFromBitmap'。  看,你可以使用这个函数从.bmp,.png,.jpg文件加载BitmapSource:

    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;
    }

要从BitmapSource获取Texture2D,您可以使用:

    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));
        }
    }

为了方便起见,我创建了这个函数:

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

答案 1 :(得分:4)

您不需要使用WIC在Metro中加载纹理,您也可以从BitmapImage创建它们(它在Metro中工作并且不那么复杂):

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;
}

请在此处查看我的回答:SharpDX load a texture in Windows Phone 8

答案 2 :(得分:2)

好消息! SharpDX的作者Alexandre Mutel让我知道微软从Direct3D11中删除了“辅助方法”。这不是SharpDX的遗漏。他还指出了我正确的方向;使用WIC加载我的纹理。我在这里找到了示例代码:

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

我只需要两个方法:LoadBitmap()和CreateTex2DFromBitmap()。我不得不将“R8G8B8A8_UNorm_SRgb”更改为“R8G8B8A8_UNorm”,但最终我得到了它的工作。而现在我的游戏在Metro中看起来很棒,所有的纹理都已到位! :)

相关问题