C# SharpDX 3.0.2 D3D11-如何从文件加载纹理并使其在着色器中工作?

C# SharpDX 3.0.2 D3D11-如何从文件加载纹理并使其在着色器中工作?,c#,directx,directx-11,sharpdx,C#,Directx,Directx 11,Sharpdx,我对D3D没有任何经验。我目前正在阅读Frank Luna关于D3D11的书,并试图通过w/o效果框架使用SharpDX制作C#中的示例。我现在坚持使用纹理。我不知道如何从文件加载纹理以及如何将其发送到着色器 官方维基已经死了。或者至少对我来说它不会加载。 我在这里搜索了一下,但只找到了一些使用SharpDX.WIC的方法,它与D2D一起使用,所以在D3D应用程序中使用一些D2D组件对我来说有点奇怪。在这里查找纹理加载程序: 用法: var device = this.DeviceManager

我对D3D没有任何经验。我目前正在阅读Frank Luna关于D3D11的书,并试图通过w/o效果框架使用SharpDX制作C#中的示例。我现在坚持使用纹理。我不知道如何从文件加载纹理以及如何将其发送到着色器

官方维基已经死了。或者至少对我来说它不会加载。
我在这里搜索了一下,但只找到了一些使用SharpDX.WIC的方法,它与D2D一起使用,所以在D3D应用程序中使用一些D2D组件对我来说有点奇怪。

在这里查找纹理加载程序:

用法:

var device = this.DeviceManager.Direct3DDevice;
var texture = TextureLoader.CreateTexture2DFromBitmap(device, TextureLoader.LoadBitmap(new SharpDX.WIC.ImagingFactory2(), "Texture2.png"));
ShaderResourceView textureView = new ShaderResourceView(device, texture);

不是Direct2D的一部分,WIC是在DirectX中加载图像的最好方式,即使在C++中,你也必须使用WIC,所以只要按照第一个答案的链接,你就可以了。 或

公共类TextureLoader
{
/// 
///使用WIC加载位图。
/// 
/// 
/// 
/// 
公共静态SharpDX.WIC.BitmapSource加载位图(SharpDX.WIC.ImagingFactory2工厂,字符串文件名)
{
var bitmapDecoder=新的SharpDX.WIC.bitmapDecoder(
工厂,
文件名,
SharpDX.WIC.DecodeOptions.CacheOnDemand
);
var formatConverter=新的SharpDX.WIC.formatConverter(工厂);
formatConverter.Initialize(
bitmapDecoder.GetFrame(0),
SharpDX.WIC.PixelFormat.Format32bppPRGBA,
SharpDX.WIC.BitmapDitherType.None,
无效的
0.0, 
SharpDX.WIC.BitmapPaletteType.Custom);
返回格式转换器;
}
/// 
///从WIC创建一个
/// 
///Direct3D11设备
///WIC位图源代码
///纹理2d
公共静态SharpDX.Direct3D11.Texture2D从位图创建texture2dfrombitmap(SharpDX.Direct3D11.Device设备,SharpDX.WIC.BitmapSource BitmapSource)
{
//分配数据流以接收WIC图像像素
int stride=bitmapSource.Size.Width*4;
使用(var buffer=new SharpDX.DataStream(bitmapSource.Size.Height*stride,true,true))
{
//将WIC的内容复制到缓冲区
bitmapSource.CopyPixels(步幅、缓冲区);
返回新的SharpDX.Direct3D11.Texture2D(设备,新的SharpDX.Direct3D11.texture2dddescription()
{
宽度=位图源.Size.Width,
高度=位图源.Size.Height,
ArraySize=1,
BindFlags=SharpDX.Direct3D11.BindFlags.ShaderResource,
用法=SharpDX.Direct3D11.ResourceUsage.Immutable,
CpuAccessFlags=SharpDX.Direct3D11.CpuAccessFlags.None,
Format=SharpDX.DXGI.Format.R8G8B8A8_UNorm,
MIP级别=1,
OptionFlags=SharpDX.Direct3D11.ResourceOptionFlags.None,
SampleDescription=新的SharpDX.DXGI.SampleDescription(1,0),
},新的SharpDX.DataRectangle(buffer.DataPointer,stride));
}
}
}

我刚刚从链接中删除了它,因此它可能需要一些更改才能使用SharpDX 3,我使用几乎相同的代码路径,但在加载阶段我有更多的选项,例如法线的非预乘、转换为Srgb等等。

很抱歉在旧线程上发布,但是使用.NETFramework中提供的功能来实现这一点不是更好吗

    if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
    {
        bitmap = bitmap.Clone(new Rectangle(0, 0, bitmap.Width, bitmap.Height), PixelFormat.Format32bppArgb);
    }
    var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
    var ret = new SharpDX.Direct3D11.Texture2D(device, new SharpDX.Direct3D11.Texture2DDescription()
    {
        Width = bitmap.Width,
        Height = bitmap.Height,
        ArraySize = 1,
        BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource,
        Usage = SharpDX.Direct3D11.ResourceUsage.Immutable,
        CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.None,
        Format = SharpDX.DXGI.Format.B8G8R8A8_UNorm,
        MipLevels = 1,
        OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None,
        SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
    }, new SharpDX.DataRectangle(data.Scan0, data.Stride));
    bitmap.UnlockBits(data);
    return ret;

我个人喜欢在参考资料中保留一些纹理(在exe中)。要从资源中获取位图,可以使用C#中的project.Properties.resources.BITMAPNAME

然后我为GDI+位图到WIC位图制作了一个小的转换函数:

    public static unsafe SharpDX.WIC.Bitmap CreateWICBitmapFromGDI(
        System.Drawing.Bitmap gdiBitmap)
    {
        var wicFactory = new ImagingFactory();
        var wicBitmap = new SharpDX.WIC.Bitmap(
            wicFactory, gdiBitmap.Width, gdiBitmap.Height,
            SharpDX.WIC.PixelFormat.Format32bppBGRA, 
            BitmapCreateCacheOption.CacheOnLoad);

        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(
            0, 0, gdiBitmap.Width, gdiBitmap.Height);
        var btmpData = gdiBitmap.LockBits(rect,
            System.Drawing.Imaging.ImageLockMode.WriteOnly,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        byte* pGDIData = (byte*)btmpData.Scan0;
        using (BitmapLock bl = wicBitmap.Lock(BitmapLockFlags.Write))
        {
            byte* pWICData = (byte*)bl.Data.DataPointer;
            for (int y = 0; y < gdiBitmap.Height; y++)
            {
                int offsetWIC = y * bl.Stride;
                int offsetGDI = y * btmpData.Stride;
                for (int x = 0; x < gdiBitmap.Width; x++)
                {
                    pWICData[offsetWIC + 0] = pGDIData[offsetGDI + 0];  //R
                    pWICData[offsetWIC + 1] = pGDIData[offsetGDI + 1];  //G
                    pWICData[offsetWIC + 2] = pGDIData[offsetGDI + 2];  //B
                    pWICData[offsetWIC + 3] = pGDIData[offsetGDI + 3];      //A
                    offsetWIC += 4;
                    offsetGDI += 4;
                }
            }
        }

        gdiBitmap.UnlockBits(btmpData);

        return wicBitmap;
    }
公共静态不安全SharpDX.WIC.Bitmap CreateWICBitmapFromGDI(
System.Drawing.Bitmap(gdiBitmap)
{
var wicFactory=new ImagingFactory();
var wicBitmap=新的SharpDX.WIC.Bitmap(
WIC工厂,gdiBitmap.宽度,gdiBitmap.高度,
SharpDX.WIC.PixelFormat.Format32bppBGRA,
BitmapCreateCacheOption.CacheOnLoad);
System.Drawing.Rectangle rect=新的System.Drawing.Rectangle(
0,0,gdiBitmap.Width,gdiBitmap.Height);
var btmpData=gdiBitmap.LockBits(rect,
System.Drawing.Imaging.ImageLockMode.WriteOnly,
系统。绘图。成像。像素格式。格式32bppargb);
字节*pGDIData=(字节*)btmpData.Scan0;
使用(BitmapLock bl=wicBitmap.Lock(BitmapLockFlags.Write))
{
字节*pWICData=(字节*)bl.Data.DataPointer;
对于(int y=0;y

这将为您创建WIC位图,然后您可以使用CreateTexture2DFromBitmap在绘图管道中使用它

在Direct3D中使用WIC作为Direct2D包的一部分进行纹理加载不是很奇怪吗?同样的问题。我只是在开发一个Direct3D11程序,但现在我用的是D3DCompiler、桌面、Direct2D1、DXGI和数学。有这么多分离的依赖项总是一起使用的目的是什么?真烦人。上面的例子很好,但并没有处理位图。另外,要获取位图,您应该
使用(var image=image.FromFile(path)){var bitmap=new bitmap(image);…}
    public static unsafe SharpDX.WIC.Bitmap CreateWICBitmapFromGDI(
        System.Drawing.Bitmap gdiBitmap)
    {
        var wicFactory = new ImagingFactory();
        var wicBitmap = new SharpDX.WIC.Bitmap(
            wicFactory, gdiBitmap.Width, gdiBitmap.Height,
            SharpDX.WIC.PixelFormat.Format32bppBGRA, 
            BitmapCreateCacheOption.CacheOnLoad);

        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(
            0, 0, gdiBitmap.Width, gdiBitmap.Height);
        var btmpData = gdiBitmap.LockBits(rect,
            System.Drawing.Imaging.ImageLockMode.WriteOnly,
            System.Drawing.Imaging.PixelFormat.Format32bppArgb);

        byte* pGDIData = (byte*)btmpData.Scan0;
        using (BitmapLock bl = wicBitmap.Lock(BitmapLockFlags.Write))
        {
            byte* pWICData = (byte*)bl.Data.DataPointer;
            for (int y = 0; y < gdiBitmap.Height; y++)
            {
                int offsetWIC = y * bl.Stride;
                int offsetGDI = y * btmpData.Stride;
                for (int x = 0; x < gdiBitmap.Width; x++)
                {
                    pWICData[offsetWIC + 0] = pGDIData[offsetGDI + 0];  //R
                    pWICData[offsetWIC + 1] = pGDIData[offsetGDI + 1];  //G
                    pWICData[offsetWIC + 2] = pGDIData[offsetGDI + 2];  //B
                    pWICData[offsetWIC + 3] = pGDIData[offsetGDI + 3];      //A
                    offsetWIC += 4;
                    offsetGDI += 4;
                }
            }
        }

        gdiBitmap.UnlockBits(btmpData);

        return wicBitmap;
    }