Example #1
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormat_Legacy legacyFormat =
                    (SurfaceFormat_Legacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotSupportedException(
                              "Unsupported legacy surface format."
                              );
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }
            int           width            = reader.ReadInt32();
            int           height           = reader.ReadInt32();
            int           levelCount       = reader.ReadInt32();
            int           levelCountOutput = levelCount;
            SurfaceFormat convertedFormat  = surfaceFormat;

            switch (surfaceFormat)
            {
            case SurfaceFormat.Dxt1:
                if (!OpenGLDevice.Instance.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                if (!OpenGLDevice.Instance.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }
            if (existingInstance == null)
            {
                texture = new Texture2D(
                    reader.GraphicsDevice,
                    width,
                    height,
                    levelCountOutput > 1,
                    convertedFormat
                    );
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level += 1)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = null;      // Don't assign this quite yet...
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                if (level >= levelCountOutput)
                {
                    continue;
                }
                // Convert the image data if required
                switch (surfaceFormat)
                {
                case SurfaceFormat.Dxt1:
                    if (!OpenGLDevice.Instance.SupportsDxt1)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Dxt3:
                    if (!OpenGLDevice.Instance.SupportsS3tc)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Dxt5:
                    if (!OpenGLDevice.Instance.SupportsS3tc)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                        levelData = DxtUtil.DecompressDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    break;

                case SurfaceFormat.Bgr565:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                }
                break;

                case SurfaceFormat.Bgra5551:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            ushort pixel = BitConverter.ToUInt16(
                                levelData,
                                offset
                                );
                            pixel = (ushort)(
                                ((pixel & 0x7FFF) << 1) |
                                ((pixel & 0x8000) >> 15)
                                );
                            levelData[offset] =
                                (byte)(pixel);
                            levelData[offset + 1] =
                                (byte)(pixel >> 8);
                            offset += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            ushort pixel = BitConverter.ToUInt16(
                                levelData,
                                offset
                                );
                            pixel = (ushort)(
                                ((pixel & 0x0FFF) << 4) |
                                ((pixel & 0xF000) >> 12)
                                );
                            levelData[offset] =
                                (byte)(pixel);
                            levelData[offset + 1] =
                                (byte)(pixel >> 8);
                            offset += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                    int bytesPerPixel = 4;                             // According to Texture.GetFormatSize()
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y += 1)
                    {
                        for (int x = 0; x < levelWidth; x += 1)
                        {
                            int color = BitConverter.ToInt32(
                                levelData,
                                y * pitch + x * bytesPerPixel
                                );
                            // R:=W
                            levelData[y * pitch + x * 4] =
                                (byte)(((color >> 16) & 0xff));
                            // G:=V
                            levelData[y * pitch + x * 4 + 1] =
                                (byte)(((color >> 8) & 0xff));
                            // B:=U
                            levelData[y * pitch + x * 4 + 2] =
                                (byte)(((color) & 0xff));
                            // A:=Q
                            levelData[y * pitch + x * 4 + 3] =
                                (byte)(((color >> 24) & 0xff));
                        }
                    }
                }
                break;
                }

                if (levelData == null &&
                    reader.BaseStream.GetType() != typeof(System.IO.MemoryStream))
                {
                    /* If the ContentReader is not backed by a
                     * MemoryStream, we have to read the data in.
                     */
                    levelData = reader.ReadBytes(levelDataSizeInBytes);
                }
                if (levelData != null)
                {
                    /* If we had to convert the data, or get the data from a
                     * non-MemoryStream, we set the data with our levelData
                     * reference.
                     */
                    texture.SetData(level, null, levelData, 0, levelData.Length);
                }
                else
                {
                    /* Ideally, we didn't have to perform any conversion or
                     * unnecessary reading. Just throw the buffer directly
                     * into SetData, skipping a redundant byte[] copy.
                     */
                    texture.SetData <byte>(
                        level,
                        null,
                        (((System.IO.MemoryStream)(reader.BaseStream)).GetBuffer()),
                        (int)reader.BaseStream.Position,
                        levelDataSizeInBytes
                        );
                    reader.BaseStream.Seek(
                        levelDataSizeInBytes,
                        System.IO.SeekOrigin.Current
                        );
                }
            }

            return(texture);
        }
Example #2
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormat_Legacy legacyFormat = (SurfaceFormat_Legacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotSupportedException("Unsupported legacy surface format.");
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }

            int width            = (reader.ReadInt32());
            int height           = (reader.ReadInt32());
            int levelCount       = (reader.ReadInt32());
            int levelCountOutput = levelCount;

            // If the system does not fully support Power of Two textures,
            // skip any mip maps supplied with any non PoT textures.
            if (levelCount > 1 && !GraphicsCapabilities.SupportsNonPowerOfTwo &&
                (!MathHelper.IsPowerOfTwo(width) || !MathHelper.IsPowerOfTwo(height)))
            {
                levelCountOutput = 1;
                System.Diagnostics.Debug.WriteLine(
                    "Device does not support non Power of Two textures. Skipping mipmaps.");
            }

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
#if IOS
            // At the moment. If a DXT Texture comes in on iOS, it's really a PVR compressed
            // texture. We need to use this hack until the content pipeline is implemented.
            // For now DXT5 means we're using 4bpp PVRCompression and DXT3 means 2bpp. Look at
            // PvrtcBitmapContent.cs for more information.:
            case SurfaceFormat.Dxt3:
                convertedFormat = SurfaceFormat.RgbaPvrtc2Bpp;
                break;

            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.RgbaPvrtc4Bpp;
                break;
#else
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt1a:
                if (!GraphicsCapabilities.SupportsDxt1)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                if (!GraphicsCapabilities.SupportsS3tc)
                {
                    convertedFormat = SurfaceFormat.Color;
                }
                break;
#endif
            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }

            if (existingInstance == null)
            {
                texture = new Texture2D(reader.GraphicsDevice, width, height, levelCountOutput > 1, convertedFormat);
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level++)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = reader.ReadBytes(levelDataSizeInBytes);
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;

                if (level >= levelCountOutput)
                {
                    continue;
                }

                //Convert the image data if required
                switch (surfaceFormat)
                {
#if !IOS
                case SurfaceFormat.Dxt1:
                case SurfaceFormat.Dxt1a:
                    if (!GraphicsCapabilities.SupportsDxt1)
                    {
                        levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                    }
                    break;

                case SurfaceFormat.Dxt3:
                    if (!GraphicsCapabilities.SupportsS3tc)
                    {
                        levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                    }
                    break;

                case SurfaceFormat.Dxt5:
                    if (!GraphicsCapabilities.SupportsS3tc)
                    {
                        levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                    }
                    break;
#endif
                case SurfaceFormat.Bgr565:
                {
                    /*
                     * // BGR -> BGR
                     * int offset = 0;
                     * for (int y = 0; y < levelHeight; y++)
                     * {
                     *      for (int x = 0; x < levelWidth; x++)
                     *      {
                     *              ushort pixel = BitConverter.ToUInt16(levelData, offset);
                     *              pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                     *              levelData[offset] = (byte)(pixel);
                     *              levelData[offset + 1] = (byte)(pixel >> 8);
                     *              offset += 2;
                     *      }
                     * }
                     */
                }
                break;

                case SurfaceFormat.Bgra5551:
                {
#if OPENGL
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x7FFF) << 1) | ((pixel & 0x8000) >> 15));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
#endif
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
#if OPENGL
                    // Shift the channels to suit OPENGL
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
#endif
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    int bytesPerPixel = surfaceFormat.GetSize();
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel);
                            levelData[y * pitch + x * 4]     = (byte)(((color >> 16) & 0xff));                                       //R:=W
                            levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff));                                        //G:=V
                            levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff));                                             //B:=U
                            levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff));                                       //A:=Q
                        }
                    }
                }
                break;
                }

                texture.SetData(level, null, levelData, 0, levelData.Length);
            }

            return(texture);
        }
Example #3
0
        protected internal override Texture2D Read(ContentReader reader, Texture2D existingInstance)
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                SurfaceFormat_Legacy legacyFormat = (SurfaceFormat_Legacy)reader.ReadInt32();
                switch (legacyFormat)
                {
                case SurfaceFormat_Legacy.Dxt1:
                    surfaceFormat = SurfaceFormat.Dxt1;
                    break;

                case SurfaceFormat_Legacy.Dxt3:
                    surfaceFormat = SurfaceFormat.Dxt3;
                    break;

                case SurfaceFormat_Legacy.Dxt5:
                    surfaceFormat = SurfaceFormat.Dxt5;
                    break;

                case SurfaceFormat_Legacy.Color:
                    surfaceFormat = SurfaceFormat.Color;
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
            else
            {
                surfaceFormat = (SurfaceFormat)reader.ReadInt32();
            }

            int width      = (reader.ReadInt32());
            int height     = (reader.ReadInt32());
            int levelCount = (reader.ReadInt32());

            SurfaceFormat convertedFormat = surfaceFormat;

            switch (surfaceFormat)
            {
#if IPHONE
            // At the moment. If a DXT Texture comes in on iOS, it's really a PVR compressed
            // texture. We need to use this hack until the content pipeline is implemented.
            // For now DXT5 means we're using 4bpp PVRCompression and DXT3 means 2bpp. Look at
            // PvrtcBitmapContent.cs for more information.:
            case SurfaceFormat.Dxt3:
                convertedFormat = SurfaceFormat.RgbaPvrtc2Bpp;
                break;

            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.RgbaPvrtc4Bpp;
                break;
#elif ANDROID || PSS
            case SurfaceFormat.Dxt1:
            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                convertedFormat = SurfaceFormat.Color;
                break;
#endif
            case SurfaceFormat.NormalizedByte4:
                convertedFormat = SurfaceFormat.Color;
                break;
            }

            if (existingInstance == null)
            {
                texture = new Texture2D(reader.GraphicsDevice, width, height, levelCount > 1, convertedFormat);
            }
            else
            {
                texture = existingInstance;
            }

            for (int level = 0; level < levelCount; level++)
            {
                int    levelDataSizeInBytes = (reader.ReadInt32());
                byte[] levelData            = reader.ReadBytes(levelDataSizeInBytes);
                int    levelWidth           = width >> level;
                int    levelHeight          = height >> level;
                //Convert the image data if required
                switch (surfaceFormat)
                {
#if ANDROID || PSS
                //no Dxt in OpenGL ES
                case SurfaceFormat.Dxt1:
                    levelData = DxtUtil.DecompressDxt1(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt3:
                    levelData = DxtUtil.DecompressDxt3(levelData, levelWidth, levelHeight);
                    break;

                case SurfaceFormat.Dxt5:
                    levelData = DxtUtil.DecompressDxt5(levelData, levelWidth, levelHeight);
                    break;
#endif
                case SurfaceFormat.Bgr565:
                {
                    /*
                     * // BGR -> BGR
                     * int offset = 0;
                     * for (int y = 0; y < levelHeight; y++)
                     * {
                     *      for (int x = 0; x < levelWidth; x++)
                     *      {
                     *              ushort pixel = BitConverter.ToUInt16(levelData, offset);
                     *              pixel = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                     *              levelData[offset] = (byte)(pixel);
                     *              levelData[offset + 1] = (byte)(pixel >> 8);
                     *              offset += 2;
                     *      }
                     * }
                     */
                }
                break;

                case SurfaceFormat.Bgra4444:
                {
                    // Shift the channels to suit GLES
                    int offset = 0;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            ushort pixel = BitConverter.ToUInt16(levelData, offset);
                            pixel                 = (ushort)(((pixel & 0x0FFF) << 4) | ((pixel & 0xF000) >> 12));
                            levelData[offset]     = (byte)(pixel);
                            levelData[offset + 1] = (byte)(pixel >> 8);
                            offset               += 2;
                        }
                    }
                }
                break;

                case SurfaceFormat.NormalizedByte4:
                {
                    int bytesPerPixel = surfaceFormat.Size();
                    int pitch         = levelWidth * bytesPerPixel;
                    for (int y = 0; y < levelHeight; y++)
                    {
                        for (int x = 0; x < levelWidth; x++)
                        {
                            int color = BitConverter.ToInt32(levelData, y * pitch + x * bytesPerPixel);
                            levelData[y * pitch + x * 4]     = (byte)(((color >> 16) & 0xff));                                       //R:=W
                            levelData[y * pitch + x * 4 + 1] = (byte)(((color >> 8) & 0xff));                                        //G:=V
                            levelData[y * pitch + x * 4 + 2] = (byte)(((color) & 0xff));                                             //B:=U
                            levelData[y * pitch + x * 4 + 3] = (byte)(((color >> 24) & 0xff));                                       //A:=Q
                        }
                    }
                }
                break;
                }

                texture.SetData(level, null, levelData, 0, levelData.Length);
            }

            return(texture);
        }