void setTexture(byte[] color, int width, int height) { if (_texture == null || _texture.Description.Width != width || _texture.Description.Height != height) { if (_texture != null) { _texture.Dispose(); } Texture2DDescription colordesc = new Texture2DDescription { BindFlags = BindFlags.ShaderResource, Format = Format.B8G8R8A8_UNorm, Width = width, Height = height, MipLevels = 1, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Dynamic, OptionFlags = ResourceOptionFlags.None, CpuAccessFlags = CpuAccessFlags.Write, ArraySize = 1 }; //テクスチャのセット _texture = new Texture2D(_device, colordesc); _effect.GetVariableByName("HandTexture").AsShaderResource().SetResource(new ShaderResourceView(_device, _texture)); } //テクスチャの書き込み var data = _texture.Map(Texture2D.CalculateSubResourceIndex(0, 0, 1), MapMode.WriteDiscard, SharpDX.Direct3D10.MapFlags.None); unsafe { var ptr = (byte *)data.DataPointer.ToPointer(); for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { ptr[(y * width + x) * 4 + 0] = color[(y * width + x) * 3 + 0]; //B ptr[(y * width + x) * 4 + 1] = color[(y * width + x) * 3 + 1]; //G ptr[(y * width + x) * 4 + 2] = color[(y * width + x) * 3 + 2]; //R ptr[(y * width + x) * 4 + 3] = 255; //A } } } _texture.Unmap(Texture2D.CalculateSubResourceIndex(0, 0, 1)); }
/// <summary> /// Captures the texture. /// </summary> /// <param name="context">The context.</param> /// <param name="source">The source.</param> /// <param name="stagingTexture">The staging texture.</param> /// <returns></returns> public static bool CaptureTexture(DeviceContext context, Texture2D source, out Texture2D stagingTexture) { stagingTexture = null; if (source == null) { return(false); } var desc = source.Description; if (source.Description.SampleDescription.Count > 1) { desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; using (var texture = new Texture2D(context.Device, desc)) { for (var i = 0; i < desc.ArraySize; ++i) { for (var level = 0; level < desc.MipLevels; ++level) { int mipSize; var index = texture.CalculateSubResourceIndex(level, i, out mipSize); context.ResolveSubresource(source, index, texture, index, desc.Format); } } desc.BindFlags = BindFlags.None; desc.Usage = ResourceUsage.Staging; desc.CpuAccessFlags = CpuAccessFlags.Read; desc.OptionFlags &= ResourceOptionFlags.TextureCube; stagingTexture = new Texture2D(context.Device, desc); context.CopyResource(texture, stagingTexture); } } else if (desc.Usage == ResourceUsage.Staging && desc.CpuAccessFlags == CpuAccessFlags.Read) { stagingTexture = source; } else { desc.BindFlags = BindFlags.None; desc.OptionFlags &= ResourceOptionFlags.TextureCube; desc.CpuAccessFlags = CpuAccessFlags.Read; desc.Usage = ResourceUsage.Staging; stagingTexture = new Texture2D(context.Device, desc); context.CopyResource(source, stagingTexture); } return(true); }
public static void Save(this Texture2D texture, DeviceContext context, Device device, string path, bool withMips) { var textureCopy = new Texture2D(device, new Texture2DDescription { Width = texture.Description.Width, Height = texture.Description.Height, MipLevels = texture.Description.MipLevels, ArraySize = texture.Description.ArraySize, Format = texture.Description.Format, Usage = ResourceUsage.Staging, SampleDescription = new SampleDescription(1, 0), BindFlags = BindFlags.None, CpuAccessFlags = CpuAccessFlags.Read, OptionFlags = ResourceOptionFlags.None }); context.CopyResource(texture, textureCopy); if (texture.Description.ArraySize == 1) { if (textureCopy.Description.Format == Format.R16G16_Float) { DataBox dataBox = context.MapSubresource( textureCopy, 0, 0, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out DataStream dataStream); AssetsMeta.Texture2DAsset asset2D = new AssetsMeta.Texture2DAsset(); asset2D.Name = path; asset2D.Data.Width = textureCopy.Description.Width; asset2D.Data.Height = textureCopy.Description.Height; asset2D.Data.ColorSpace = ColorSpaceEnum.Linear; asset2D.Data.ChannelsCount = ChannelsCountEnum.Two; asset2D.Data.BytesPerChannel = BytesPerChannelEnum.Two; asset2D.Data.buffer = ReadFully(dataStream); AssetsManagerInstance.GetManager().FSWorker.CreateAssetFile(asset2D, true); context.UnmapSubresource(textureCopy, 0); textureCopy.Dispose(); return; } InternalSaveTexture($"{path}.png", 0, 0, Factory, textureCopy, context); textureCopy.Dispose(); return; } AssetsMeta.TextureCubeAsset asset = new AssetsMeta.TextureCubeAsset(); asset.Name = path; asset.Data.Width = textureCopy.Description.Width; asset.Data.Height = textureCopy.Description.Height; asset.Data.ColorSpace = ColorSpaceEnum.Linear; asset.Data.ChannelsCount = 4; asset.Data.BytesPerChannel = 2; asset.Data.MipLevels = withMips ? textureCopy.Description.MipLevels : 1; asset.Data.buffer = new byte[6][][]; for (int i = 0; i < 6; i++) { asset.Data.buffer[i] = new byte[asset.Data.MipLevels][]; for (int mip = 0; mip < asset.Data.MipLevels; mip++) { DataBox dataBox = context.MapSubresource( textureCopy, mip, i, MapMode.Read, SharpDX.Direct3D11.MapFlags.None, out DataStream dataStream); byte[] allMipBytes = ReadFully(dataStream); dataStream.Dispose(); int mipSize = (int)(asset.Data.Width * Math.Pow(0.5, mip)); int pitch = mipSize * asset.Data.ChannelsCount * asset.Data.BytesPerChannel; int n = mipSize * pitch; asset.Data.buffer[i][mip] = new byte[n]; for (int j = 0; j < mipSize; j++) { for (int k = 0; k < pitch; k++) { asset.Data.buffer[i][mip][j * pitch + k] = allMipBytes[j * dataBox.RowPitch + k]; } } context.UnmapSubresource(textureCopy, textureCopy.CalculateSubResourceIndex(mip, i, out int m)); // Dont work cause wrong dataBox.RowPitch on mip levels issue. // asset.Data.buffer[i][mip] = ReadFully(dataStream); } } AssetsManagerInstance.GetManager().FSWorker.CreateAssetFile(asset, true); // DEBUG RO PNG /*if (textureCopy.Description.MipLevels != 5) { * textureCopy.Dispose(); * return; * } * * for (int mip = 0; mip < textureCopy.Description.MipLevels; mip++) { * for (int i = 0; i < texture.Description.ArraySize; i++) { * InternalSaveTexture($"{path}_{CubePostfixes[i]}_mip{mip}.png", i, mip, Factory, textureCopy, context); * } * }*/ textureCopy.Dispose(); }