コード例 #1
0
ファイル: DDSTexture.cs プロジェクト: zkov96/SuprimeMapEditor
    DDS_HEADER_DXT10 ReadHDXT10()
    {
        DDS_HEADER_DXT10 header = new DDS_HEADER_DXT10();

        header.dxgiFormat        = ReadEnum <DDS_HEADER_DXT10.DXGI_FORMAT>();
        header.resourceDimension = ReadEnum <DDS_HEADER_DXT10.D3D10_RESOURCE_DIMENSION>();
        header.miscFlag          = ReadUInt();
        header.arraySize         = ReadUInt();
        header.miscFlags2        = ReadUInt();

        return(header);
    }
コード例 #2
0
        public void Save(Stream ddsStream, bool keepOpen = false)
        {
            if (!Loaded)
            {
                return;
            }
            using (BinaryWriter ddsWriter = new BinaryWriter(ddsStream, System.Text.Encoding.Default, keepOpen)) {
                DDSHeader dds = Header.ToDDSHeader();
                ddsWriter.Write(dds);
                if (dds.format.fourCC == 808540228)
                {
                    DDS_HEADER_DXT10 d10 = new DDS_HEADER_DXT10 {
                        format    = (uint)Header.format,
                        dimension = D3D10_RESOURCE_DIMENSION.TEXTURE2D,
                        misc      = (uint)(Header.IsCubemap() ? 0x4 : 0),
                        size      = (uint)(Header.IsCubemap() ? 1 : Header.surfaces),
                        misc2     = 0
                    };
                    ddsWriter.Write(d10);
                }
                if (Header.Format() == TextureType.Unknown)
                {
                    ddsWriter.Write(RawData);
                }
                else
                {
                    for (int i = 0; i < Size; ++i)
                    {
                        if ((byte)Header.format > 72)
                        {
                            ddsWriter.Write(Color3[i]);
                            ddsWriter.Write(Color4[i]);
                            ddsWriter.Write(Color5[i]);
                        }

                        if ((byte)Header.format < 80)
                        {
                            ddsWriter.Write(Color1[i]);
                            ddsWriter.Write(Color2[i]);
                        }
                    }
                }
            }
        }
コード例 #3
0
 public void Save(Stream output, bool keepOpen = false)
 {
     if (!loaded)
     {
         return;
     }
     using (BinaryWriter ddsWriter = new BinaryWriter(output, System.Text.Encoding.Default, keepOpen)) {
         DDSHeader dds = header.ToDDSHeader();
         ddsWriter.Write(dds);
         if (dds.format.fourCC == 808540228)
         {
             DDS_HEADER_DXT10 d10 = new DDS_HEADER_DXT10 {
                 format    = (uint)header.format,
                 dimension = D3D10_RESOURCE_DIMENSION.TEXTURE2D,
                 misc      = (uint)(header.IsCubemap() ? 0x4 : 0),
                 size      = (uint)(header.IsCubemap() ? 1 : header.surfaces),
                 misc2     = 0
             };
             ddsWriter.Write(d10);
         }
         ddsWriter.Write(data, 0, (int)header.dataSize);
     }
 }
コード例 #4
0
        private static ShaderResourceView InitTextureFromData(Device d3dDevice, DeviceContext context, DDS_HEADER header, DDS_HEADER_DXT10?header10, byte[] bitData, int offset, int maxsize, out bool isCubeMap)
        {
            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            ResourceDimension resDim = ResourceDimension.Unknown;
            int    arraySize         = 1;
            Format format            = Format.Unknown;

            isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((ResourceDimension)d3d10ext.resourceDimension)
                {
                case ResourceDimension.Texture1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case ResourceDimension.Texture2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        isCubeMap  = true;
                    }
                    depth = 1;
                    break;

                case ResourceDimension.Texture3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (ResourceDimension)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.Unknown)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = ResourceDimension.Texture3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = ResourceDimension.Texture2D;
                }
            }

            Resource resource = null;


            GCHandle pinnedArray = GCHandle.Alloc(bitData, GCHandleType.Pinned);
            IntPtr   pointer     = pinnedArray.AddrOfPinnedObject();
            var      boxes       = FillInitData(pointer, width, height, depth, mipCount, arraySize, format, 0, 0, offset);


            switch (resDim)
            {
            case ResourceDimension.Unknown:
                break;

            case ResourceDimension.Buffer:
                break;

            case ResourceDimension.Texture1D:
                resource = new Texture1D(d3dDevice, new Texture1DDescription()
                {
                    BindFlags      = BindFlags.ShaderResource,
                    Format         = format,
                    ArraySize      = arraySize,
                    Width          = width,
                    CpuAccessFlags = CpuAccessFlags.None,
                    MipLevels      = mipCount,
                    OptionFlags    = ResourceOptionFlags.None,
                    Usage          = ResourceUsage.Default,
                }, boxes.ToArray());
                break;

            case ResourceDimension.Texture2D:
                resource = new Texture2D(d3dDevice, new Texture2DDescription()
                {
                    ArraySize         = arraySize,
                    BindFlags         = BindFlags.ShaderResource,
                    Format            = format,
                    Height            = height,
                    Width             = width,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    MipLevels         = mipCount,
                    OptionFlags       = ResourceOptionFlags.None,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default
                }, boxes.ToArray());
                break;

            case ResourceDimension.Texture3D:
                resource = new Texture3D(d3dDevice, new Texture3DDescription()
                {
                    Depth          = depth,
                    BindFlags      = BindFlags.ShaderResource,
                    Format         = format,
                    Height         = height,
                    Width          = width,
                    CpuAccessFlags = CpuAccessFlags.None,
                    MipLevels      = mipCount,
                    OptionFlags    = ResourceOptionFlags.None,
                    Usage          = ResourceUsage.Default
                }, boxes.ToArray());
                break;

            default:
                break;
            }
            pinnedArray.Free();


            var resourceView = new ShaderResourceView(d3dDevice, resource);

            return(resourceView);
        }
コード例 #5
0
ファイル: ImageTextureUtil.cs プロジェクト: wriley/SEToolbox
        private static byte[] ReadTextureFile(Stream stream, int depthSlice, ref int width, ref int height, out uint fourCC, out DXGI_FORMAT dxgiFormat)
        {
            dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;

            var reader = new BinaryReader(stream);

            try
            {
                var magicNumber = reader.ReadUInt32();
                if (magicNumber != 0x20534444)
                {
                    fourCC = 0;
                    return(null);
                }

                var header = MarshalTo <DDS_HEADER>(reader.ReadBytes(DDS_HEADER.SizeInBytes));
                fourCC = header.ddspf.dwFourCC;

                UInt32 bytesPerPixel;
                UInt32 dwPitchOrLinearSize;

                var slices = 1;
                if (((DDSCAPS2)header.dwCaps2 & DDSCAPS2.DDSCAPS2_CUBEMAP) != 0)
                {
                    slices = 6;
                }

                bytesPerPixel = header.dwPitchOrLinearSize / (header.dwWidth * header.dwHeight);

                var c        = header.dwCaps2;
                var mipCount = (int)header.dwMipMapCount;
                if (mipCount == 0)
                {
                    mipCount = 1;
                }

                if (header.ddspf.dwFlags == (uint)PixelFormatFlags.FourCC && fourCC == (uint)DDS_FOURCC.DX10)
                {
                    DDS_HEADER_DXT10 dx10Header = MarshalTo <DDS_HEADER_DXT10>(reader.ReadBytes(DDS_HEADER_DXT10.SizeInBytes));
                    dxgiFormat = dx10Header.dxgiFormat;

                    switch (dx10Header.dxgiFormat)
                    {
                    case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
                    case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB:
                    case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
                    case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC6H_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
                    case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16:
                    case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS:
                    case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                        // The block-size is 8 bytes for DXT1, BC1, and BC4 formats, and 16 bytes for other block-compressed formats.
                        UInt32 blockSize = 8;
                        // For block-compressed formats, compute the pitch as:
                        dwPitchOrLinearSize = Math.Max(1, ((header.dwWidth + 3) / 4)) * blockSize;
                        break;

                    case DXGI_FORMAT.DXGI_FORMAT_R8G8_B8G8_UNORM:
                    case DXGI_FORMAT.DXGI_FORMAT_G8R8_G8B8_UNORM:
                        //For R8G8_B8G8, G8R8_G8B8, legacy UYVY-packed, and legacy YUY2-packed formats, compute the pitch as:
                        dwPitchOrLinearSize = ((header.dwWidth + 1) >> 1) * 4;
                        break;

                    default:
                        //case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
                        // For other formats, compute the pitch as:
                        bytesPerPixel       = header.ddspf.dwSize;
                        dwPitchOrLinearSize = (header.dwWidth * bytesPerPixel + 7) / 8;
                        break;
                    }
                    //bytesPerPixel = BitsPerPixel(dx10Header.dxgiFormat);
                }

                if (bytesPerPixel == 0)
                {
                    width  = (int)header.dwWidth;
                    height = (int)header.dwHeight;
                    int size = (int)(reader.BaseStream.Length - reader.BaseStream.Position);
                    return(reader.ReadBytes(size));
                }

                for (var slice = 0; slice < slices; slice++)
                {
                    uint w = header.dwWidth == 0 ? 1 : header.dwWidth;
                    uint h = header.dwHeight == 0 ? 1 : header.dwHeight;

                    for (var map = 0; map < mipCount; map++)
                    {
                        var size = (int)(bytesPerPixel * w * h);
                        if (depthSlice == slice && ((width <= 0 && height <= 0) || (w == width && h == height)))
                        {
                            width  = (int)w;
                            height = (int)h;
                            return(reader.ReadBytes(size));
                        }
                        else
                        {
                            if (stream.CanSeek)
                            {
                                reader.BaseStream.Seek(size, SeekOrigin.Current);
                            }
                            else
                            {
                                // hack for VRage.Compression.MyStreamWrapper
                                for (int i = 0; i < size; i++)
                                {
                                    reader.BaseStream.ReadByte();
                                }
                            }
                        }

                        w = w >> 1;
                        h = h >> 1;
                        if (w == 0)
                        {
                            w = 1;
                        }
                        if (h == 0)
                        {
                            h = 1;
                        }
                    }

                    reader.BaseStream.Seek(27, SeekOrigin.Current);
                }

                return(null);
            }
            catch
            {
                fourCC = 0;
                return(null);
            }
        }
コード例 #6
0
        static Resource CreateTextureFromDDS(Device d3dDevice, DDS_HEADER header, DDS_HEADER_DXT10?header10, byte[] bitData, int offset, int maxsize, out bool isCubeMap)
        {
            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            ResourceDimension resDim = ResourceDimension.Unknown;
            int    arraySize         = 1;
            Format format            = Format.Unknown;

            isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((ResourceDimension)d3d10ext.resourceDimension)
                {
                case ResourceDimension.Texture1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case ResourceDimension.Texture2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        isCubeMap  = true;
                    }
                    depth = 1;
                    break;

                case ResourceDimension.Texture3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (ResourceDimension)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.Unknown)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = ResourceDimension.Texture3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = ResourceDimension.Texture2D;
                }
            }
            var resource = d3dDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                             new ResourceDescription()
            {
                //Alignment = -1,
                Dimension         = resDim,
                DepthOrArraySize  = (short)arraySize,
                Flags             = ResourceFlags.None,
                Format            = format,
                Height            = height,
                Layout            = TextureLayout.Unknown,
                MipLevels         = (short)mipCount,
                SampleDescription = new SampleDescription(1, 0),
                Width             = width,
            },
                                                             ResourceStates.GenericRead);

            FillInitData(resource, width, height, depth, mipCount, arraySize, format, 0, 0, bitData, offset);

            return(resource);
        }
コード例 #7
0
        public static Format TextureInfo(byte[] data)
        {
            // bool isCubeMap;

            // Validate DDS file in memory
            DDS_HEADER header = new DDS_HEADER();

            int ddsHeaderSize   = Marshal.SizeOf(header);
            int ddspfSize       = Marshal.SizeOf(new DDS_PIXELFORMAT());
            int ddsHeader10Size = Marshal.SizeOf(new DDS_HEADER_DXT10());

            if (data.Length < (sizeof(uint) + ddsHeaderSize))
            {
                throw new Exception();
            }

            //first is magic number
            int dwMagicNumber = BitConverter.ToInt32(data, 0);

            if (dwMagicNumber != DDS_MAGIC)
            {
                throw new Exception();
            }

            header = ByteArrayToStructure <DDS_HEADER>(data, 4, ddsHeaderSize);

            // Verify header to validate DDS file
            if (header.size != ddsHeaderSize || header.ddspf.size != ddspfSize)
            {
                throw new Exception();
            }

            // Check for DX10 extension
            bool bDXT10Header = false;

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                // Must be long enough for both headers and magic value
                if (data.Length < (ddsHeaderSize + 4 + ddsHeader10Size))
                {
                    throw new Exception();
                }

                bDXT10Header = true;
            }

            int offset = 4 + ddsHeaderSize + (bDXT10Header ? ddsHeader10Size : 0);

            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);
            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);
            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);

            DDS_HEADER_DXT10?header10 = null;

            if (bDXT10Header)
            {
                header10 = ByteArrayToStructure <DDS_HEADER_DXT10>(data, 4 + ddsHeaderSize, ddsHeader10Size);
            }

            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            D3D10_RESOURCE_DIMENSION resDim = D3D10_RESOURCE_DIMENSION.UNKNOWN;
            int    arraySize = 1;
            Format format    = Format.UNKNOWN;
            // isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((D3D10_RESOURCE_DIMENSION)d3d10ext.resourceDimension)
                {
                case D3D10_RESOURCE_DIMENSION.TEXTURE1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case D3D10_RESOURCE_DIMENSION.TEXTURE2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        // isCubeMap = true;
                    }
                    depth = 1;
                    break;

                case D3D10_RESOURCE_DIMENSION.TEXTURE3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (D3D10_RESOURCE_DIMENSION)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.UNKNOWN)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = D3D10_RESOURCE_DIMENSION.TEXTURE3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        // isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = D3D10_RESOURCE_DIMENSION.TEXTURE2D;
                }
            }

            return(format);
        }
コード例 #8
0
        private static byte[] ReadTextureFile(string filename, int depthSlice, ref int width, ref int height, out uint fourCC)
        {
            if (!File.Exists(filename))
            {
                fourCC = 0;
                return(null);
            }

            using (var stream = File.OpenRead(filename))
            {
                var reader = new BinaryReader(stream);
                try
                {
                    var magicNumber = reader.ReadUInt32();
                    if (magicNumber != 0x20534444)
                    {
                        fourCC = 0;
                        return(null);
                    }

                    var header = MarshalTo <DDS_HEADER>(reader.ReadBytes(DDS_HEADER.SizeInBytes));
                    fourCC = header.ddspf.dwFourCC;

                    if (header.ddspf.dwFlags == (uint)PixelFormatFlags.FourCC && fourCC == (uint)DDS_FOURCC.DX10)
                    {
                        DDS_HEADER_DXT10 dx10Header = MarshalTo <DDS_HEADER_DXT10>(reader.ReadBytes(DDS_HEADER_DXT10.SizeInBytes));
                    }


                    var slices = 1;
                    if (((DDSCAPS2)header.dwCaps2 & DDSCAPS2.DDSCAPS2_CUBEMAP) != 0)
                    {
                        slices = 6;
                    }

                    var bytesPerPixel = header.dwPitchOrLinearSize / (header.dwWidth * header.dwHeight);


                    var c        = header.dwCaps2;
                    var mipCount = (int)header.dwMipMapCount;
                    if (mipCount == 0)
                    {
                        mipCount = 1;
                    }


                    for (var slice = 0; slice < slices; slice++)
                    {
                        uint w = header.dwWidth == 0 ? 1 : header.dwWidth;
                        uint h = header.dwHeight == 0 ? 1 : header.dwHeight;

                        for (var map = 0; map < mipCount; map++)
                        {
                            var size = (int)(bytesPerPixel * w * h);
                            if (depthSlice == slice && ((width <= 0 && height <= 0) || (w == width && h == height)))
                            {
                                width  = (int)w;
                                height = (int)h;
                                return(reader.ReadBytes(size));
                            }
                            else
                            {
                                reader.BaseStream.Seek(size, SeekOrigin.Current);
                            }

                            w = w >> 1;
                            h = h >> 1;
                            if (w == 0)
                            {
                                w = 1;
                            }
                            if (h == 0)
                            {
                                h = 1;
                            }
                        }

                        reader.BaseStream.Seek(27, SeekOrigin.Current);
                    }

                    return(null);
                }
                catch
                {
                    fourCC = 0;
                    return(null);
                }
            }
        }
コード例 #9
0
        private static byte[] ReadTextureFile(string filename, int depthSlice, ref int width, ref int height, out uint fourCC, out DXGI_FORMAT dxgiFormat)
        {
            dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;
            if (!File.Exists(filename))
            {
                fourCC = 0;
                return(null);
            }

            using (var stream = File.OpenRead(filename))
            {
                var reader = new BinaryReader(stream);
                try
                {
                    var magicNumber = reader.ReadUInt32();
                    if (magicNumber != 0x20534444)
                    {
                        fourCC = 0;
                        return(null);
                    }

                    var header = MarshalTo <DDS_HEADER>(reader.ReadBytes(DDS_HEADER.SizeInBytes));
                    fourCC = header.ddspf.dwFourCC;

                    if (header.ddspf.dwFlags == (uint)PixelFormatFlags.FourCC && fourCC == (uint)DDS_FOURCC.DX10)
                    {
                        DDS_HEADER_DXT10 dx10Header = MarshalTo <DDS_HEADER_DXT10>(reader.ReadBytes(DDS_HEADER_DXT10.SizeInBytes));
                        dxgiFormat = dx10Header.dxgiFormat;

                        UInt32 dwPitchOrLinearSize;
                        switch (dx10Header.dxgiFormat)
                        {
                        case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
                        case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB:
                        case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
                        case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC6H_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
                        case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16:
                        case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS:
                        case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
                            // The block-size is 8 bytes for DXT1, BC1, and BC4 formats, and 16 bytes for other block-compressed formats.
                            UInt32 blockSize = 8;
                            // For block-compressed formats, compute the pitch as:
                            dwPitchOrLinearSize = Math.Max(1, ((header.dwWidth + 3) / 4)) * blockSize;
                            break;

                        case DXGI_FORMAT.DXGI_FORMAT_R8G8_B8G8_UNORM:
                        case DXGI_FORMAT.DXGI_FORMAT_G8R8_G8B8_UNORM:
                            //For R8G8_B8G8, G8R8_G8B8, legacy UYVY-packed, and legacy YUY2-packed formats, compute the pitch as:
                            dwPitchOrLinearSize = ((header.dwWidth + 1) >> 1) * 4;
                            break;

                        default:
                            //case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
                            // For other formats, compute the pitch as:
                            UInt32 bpp = header.ddspf.dwSize;
                            dwPitchOrLinearSize = (header.dwWidth * bpp + 7) / 8;
                            break;
                        }

                        for (int iArrayElement = 0; iArrayElement < dx10Header.arraySize; iArrayElement++)
                        {
                            for (int iMipLevel = 0; iMipLevel < header.dwMipMapCount; iMipLevel++)
                            {
                                // TODO: load the Dx10 texture.
                            }
                        }

                        //dx10Header.miscFlags2
                        //dx10Header.arraySize

                        //return null;
                    }

                    var slices = 1;
                    if (((DDSCAPS2)header.dwCaps2 & DDSCAPS2.DDSCAPS2_CUBEMAP) != 0)
                    {
                        slices = 6;
                    }

                    var bytesPerPixel = header.dwPitchOrLinearSize / (header.dwWidth * header.dwHeight);


                    var c        = header.dwCaps2;
                    var mipCount = (int)header.dwMipMapCount;
                    if (mipCount == 0)
                    {
                        mipCount = 1;
                    }


                    for (var slice = 0; slice < slices; slice++)
                    {
                        uint w = header.dwWidth == 0 ? 1 : header.dwWidth;
                        uint h = header.dwHeight == 0 ? 1 : header.dwHeight;

                        for (var map = 0; map < mipCount; map++)
                        {
                            var size = (int)(bytesPerPixel * w * h);
                            if (depthSlice == slice && ((width <= 0 && height <= 0) || (w == width && h == height)))
                            {
                                width  = (int)w;
                                height = (int)h;
                                return(reader.ReadBytes(size));
                            }
                            else
                            {
                                reader.BaseStream.Seek(size, SeekOrigin.Current);
                            }

                            w = w >> 1;
                            h = h >> 1;
                            if (w == 0)
                            {
                                w = 1;
                            }
                            if (h == 0)
                            {
                                h = 1;
                            }
                        }

                        reader.BaseStream.Seek(27, SeekOrigin.Current);
                    }

                    return(null);
                }
                catch
                {
                    fourCC = 0;
                    return(null);
                }
            }
        }