Пример #1
0
        private void InitWithDDSBitmap(BinaryReader reader)
        {
            UInt32 magic = reader.ReadUInt32();
            UInt32 size  = reader.ReadUInt32();

            if (magic != DDSMagic || size != 124)
            {
                throw new InvalidDataException("Invalid DDS file header");
            }
            // UInt32 flags =
            reader.ReadUInt32();
            int height            = reader.ReadInt32();
            int width             = reader.ReadInt32();
            int pitchOrLinearSize = (int)reader.ReadUInt32();

            // UInt32 depth =
            reader.ReadUInt32();
            UInt32 mipMapCount = reader.ReadUInt32();

            reader.ReadBytes(11 * 4);
            // Read pixel format
            reader.ReadUInt32();             // Structure size (32 bytes)
            DDSPFFlags pfFlags  = (DDSPFFlags)reader.ReadUInt32();
            UInt32     pfFourCC = reader.ReadUInt32();

            // UInt32 pfRGBBitCount =
            reader.ReadUInt32();
            // UInt32 pfRBitMask =
            reader.ReadUInt32();
            // UInt32 pfGBitMask =
            reader.ReadUInt32();
            // UInt32 pfBBitMask =
            reader.ReadUInt32();
            // UInt32 pfABitMask =
            reader.ReadUInt32();
            // read the rest of header
            // UInt32 caps =
            reader.ReadUInt32();
            // UInt32 caps2 =
            reader.ReadUInt32();
            // UInt32 caps3 =
            reader.ReadUInt32();
            // UInt32 caps4 =
            reader.ReadUInt32();
            // UInt32 reserved2 =
            reader.ReadUInt32();

            Format format;

            if ((pfFlags & DDSPFFlags.RGB) != 0)
            {
                format = Format.R8G8B8A8_UNorm;
            }
            else
            {
                switch ((DDSFourCC)pfFourCC)
                {
                case DDSFourCC.DXT1:
                    format = Format.BC1_RGB_UNorm_Block;
                    break;

                case DDSFourCC.DXT3:
                    format = Format.BC2_UNorm_Block;
                    break;

                case DDSFourCC.DXT5:
                    format = Format.BC3_UNorm_Block;
                    break;

                default:
                    throw new InvalidDataException("Unsupported texture format");
                }
            }
            SurfaceSize = ImageSize = new Size(width, height);
            mipMapCount = 1;
            if (mipMapCount > 1 && mipMapCount != GraphicsUtility.CalculateMipLevelCount(width, height))
            {
                throw new NotSupportedException();
            }
            Action deferredCommands = () => EnsurePlatformTexture(format, width, height, mipMapCount > 1);

            MemoryUsed = 0;
            for (int level = 0; level < mipMapCount; level++)
            {
                var levelCopy = level;
                var buffer    = ReadTextureData(reader, GraphicsUtility.CalculateMipLevelDataSize(levelCopy, format, width, height));
                deferredCommands += () => platformTexture.SetData(levelCopy, buffer);
            }
            Window.Current.InvokeOnRendering(deferredCommands);
        }
Пример #2
0
        private void InitWithKTXTexture(BinaryReader reader)
        {
            var identifier = reader.ReadBytes(12);

            if (identifier[1] != 'K' || identifier[2] != 'T' || identifier[3] != 'X')
            {
                throw new InvalidDataException("Invalid KTX header");
            }
            var endiannes = reader.ReadUInt32();

            if (endiannes != 0x04030201)
            {
                throw new InvalidDataException("Unsupported endiannes");
            }
            var glType                = reader.ReadInt32();
            var glTypeSize            = reader.ReadInt32();
            var glFormat              = reader.ReadInt32();
            var glInternalFormat      = reader.ReadInt32();
            var glBaseInternalFormat  = reader.ReadInt32();
            var pixelWidth            = reader.ReadInt32();
            var pixelHeight           = reader.ReadInt32();
            var pixelDepth            = reader.ReadInt32();
            var numberOfArrayElements = reader.ReadInt32();
            var numberOfFaces         = reader.ReadInt32();
            var numberOfMipmapLevels  = Math.Max(1, reader.ReadInt32());
            var bytesOfKeyValueData   = reader.ReadInt32();

            reader.ReadBytes(bytesOfKeyValueData);
            if (numberOfArrayElements != 0)
            {
                throw new InvalidDataException("Array textures are not supported");
            }
            if (numberOfFaces != 1)
            {
                throw new InvalidDataException("Cubemap textures are not supported");
            }
            if (pixelDepth != 0)
            {
                throw new InvalidDataException("3D Textures are not supported");
            }
            if ((pixelWidth & 3) != 0 || (pixelHeight & 3) != 0)
            {
                throw new InvalidDataException("Texture dimensions should multiple of 4");
            }
            if (numberOfMipmapLevels > 1 && numberOfMipmapLevels != GraphicsUtility.CalculateMipLevelCount(pixelWidth, pixelHeight))
            {
                throw new InvalidDataException();
            }
            var format    = ConvertGLFormat(glInternalFormat, glBaseInternalFormat, glFormat, glType);
            var etcFormat =
                format == Format.ETC1_R8G8B8_UNorm_Block ||
                format == Format.ETC2_R8G8B8_UNorm_Block ||
                format == Format.ETC2_R8G8B8A1_UNorm_Block ||
                format == Format.ETC2_R8G8B8A8_UNorm_Block;

            SurfaceSize = ImageSize = new Size(pixelWidth, pixelHeight);
            Action deferredCommands = null;

            for (int level = 0; level < numberOfMipmapLevels; level++)
            {
                var levelCopy  = level;
                var dataLength = reader.ReadInt32();
                var data       = ReadTextureData(reader, dataLength);
                GraphicsUtility.CalculateMipLevelSize(levelCopy, pixelWidth, pixelHeight, out var levelWidth, out var levelHeight);
                MemoryUsed        = 0;
                deferredCommands += () => {
                    var formatFeatures = PlatformRenderer.Context.GetFormatFeatures(format);
                    if (etcFormat && (formatFeatures & FormatFeatures.Sample) == 0)
                    {
                        var rgba8Data = Marshal.AllocHGlobal(levelWidth * levelHeight * 4);
                        try {
                            Etc2Decoder.Decode(data, rgba8Data, levelWidth, levelHeight, format);
                            EnsurePlatformTexture(Format.R8G8B8A8_UNorm, pixelWidth, pixelHeight, numberOfMipmapLevels > 1);
                            platformTexture.SetData(levelCopy, rgba8Data);
                        } finally {
                            Marshal.FreeHGlobal(rgba8Data);
                        }
                    }
                    else
                    {
                        EnsurePlatformTexture(format, pixelWidth, pixelHeight, numberOfMipmapLevels > 1);
                        platformTexture.SetData(levelCopy, data);
                    }
                };
            }
            Window.Current.InvokeOnRendering(deferredCommands);
        }
Пример #3
0
        private void InitWithPVRTexture(BinaryReader reader)
        {
            var version = reader.ReadUInt32();

            if (version != PVRMagic)
            {
                throw new Exception("Invalid PVR header");
            }
            reader.ReadUInt32();             // flags
            var pvrFormat = (PVRFormat)reader.ReadUInt64();

            reader.ReadUInt32();             // color space
            reader.ReadUInt32();             // channel type
            var height = reader.ReadInt32();
            var width  = reader.ReadInt32();

            reader.ReadUInt32();             // depth
            reader.ReadUInt32();             // num surfaces
            reader.ReadUInt32();             // num faces
            var numMipmaps   = reader.ReadInt32();
            var metaDataSize = reader.ReadInt32();

            if (metaDataSize > 0)
            {
                reader.ReadChars(metaDataSize);
            }
            Format format;

            switch (pvrFormat)
            {
            case PVRFormat.ETC1:
                format = Format.ETC1_R8G8B8_UNorm_Block;
                break;

            case PVRFormat.PVRTC_2_RGBA:
                format = Format.PVRTC1_2Bpp_UNorm_Block;
                break;

            case PVRFormat.PVRTC_4_RGBA:
                format = Format.PVRTC1_4Bpp_UNorm_Block;
                break;

            case PVRFormat.RGB565:
                format = Format.R5G6B5_UNorm_Pack16;
                break;

            case PVRFormat.RGBA4444:
                format = Format.R4G4B4A4_UNorm_Pack16;
                break;

            case PVRFormat.RGBA8888:
                format = Format.R8G8B8A8_UNorm;
                break;

            default:
                throw new NotSupportedException();
            }
            SurfaceSize = ImageSize = new Size(width, height);
            if (numMipmaps > 1 && numMipmaps != GraphicsUtility.CalculateMipLevelCount(width, height))
            {
                throw new NotSupportedException();
            }
            Action deferredCommands = () => EnsurePlatformTexture(format, width, height, numMipmaps > 1);

            MemoryUsed = 0;
            for (int level = 0; level < numMipmaps; level++)
            {
                var levelCopy = level;
                var buffer    = ReadTextureData(reader, GraphicsUtility.CalculateMipLevelDataSize(levelCopy, format, width, height));
                deferredCommands += () => platformTexture.SetData(levelCopy, buffer);
            }
            Window.Current.InvokeOnRendering(deferredCommands);
        }