Ejemplo n.º 1
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                /* These integer values are based on the enum values
                 * from previous XNA versions.
                 * -flibit
                 */
                int legacyFormat = reader.ReadInt32();
                if (legacyFormat == 1)
                {
                    surfaceFormat = SurfaceFormat.ColorBgraEXT;
                }
                else if (legacyFormat == 28)
                {
                    surfaceFormat = SurfaceFormat.Dxt1;
                }
                else if (legacyFormat == 30)
                {
                    surfaceFormat = SurfaceFormat.Dxt3;
                }
                else if (legacyFormat == 32)
                {
                    surfaceFormat = SurfaceFormat.Dxt5;
                }
                else
                {
                    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;

            // Check to see if we need to convert the surface data
            SurfaceFormat convertedFormat = surfaceFormat;

            if (surfaceFormat == SurfaceFormat.Dxt1 &&
                !reader.GraphicsDevice.GLDevice.SupportsDxt1)
            {
                convertedFormat = SurfaceFormat.Color;
            }
            else if ((surfaceFormat == SurfaceFormat.Dxt3 ||
                      surfaceFormat == SurfaceFormat.Dxt5) &&
                     !reader.GraphicsDevice.GLDevice.SupportsS3tc)
            {
                convertedFormat = SurfaceFormat.Color;
            }

            // Check for duplicate instances
            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;
                }

                // Swap the image data if required.
                if (reader.platform == 'x')
                {
                    if (surfaceFormat == SurfaceFormat.Color ||
                        surfaceFormat == SurfaceFormat.ColorBgraEXT)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapColor(
                            levelData
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        if (levelData == null)
                        {
                            levelData = reader.ReadBytes(levelDataSizeInBytes);
                        }
                        levelData = X360TexUtil.SwapDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                }

                // Convert the image data if required
                if (surfaceFormat == SurfaceFormat.Dxt1 &&
                    !reader.GraphicsDevice.GLDevice.SupportsDxt1)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt1(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }
                else if (surfaceFormat == SurfaceFormat.Dxt3 &&
                         !reader.GraphicsDevice.GLDevice.SupportsS3tc)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt3(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }
                else if (surfaceFormat == SurfaceFormat.Dxt5 &&
                         !reader.GraphicsDevice.GLDevice.SupportsS3tc)
                {
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    levelData = DxtUtil.DecompressDxt5(
                        levelData,
                        levelWidth,
                        levelHeight
                        );
                }

                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);
        }
Ejemplo n.º 2
0
        protected internal override Texture2D Read(
            ContentReader reader,
            Texture2D existingInstance
            )
        {
            Texture2D texture = null;

            SurfaceFormat surfaceFormat;

            if (reader.version < 5)
            {
                /* These integer values are based on the enum values
                 * from previous XNA versions.
                 * -flibit
                 */
                int legacyFormat = reader.ReadInt32();
                if (legacyFormat == 1)
                {
                    surfaceFormat = SurfaceFormat.ColorBgraEXT;
                }
                else if (legacyFormat == 28)
                {
                    surfaceFormat = SurfaceFormat.Dxt1;
                }
                else if (legacyFormat == 30)
                {
                    surfaceFormat = SurfaceFormat.Dxt3;
                }
                else if (legacyFormat == 32)
                {
                    surfaceFormat = SurfaceFormat.Dxt5;
                }
                else
                {
                    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;

            GraphicsDevice device = reader.ContentManager.GetGraphicsDevice();

            // Check to see if we need to convert the surface data
            SurfaceFormat convertedFormat = surfaceFormat;

            if (surfaceFormat == SurfaceFormat.Dxt1 &&
                !device.GLDevice.SupportsDxt1)
            {
                convertedFormat = SurfaceFormat.Color;
            }
            else if ((surfaceFormat == SurfaceFormat.Dxt3 ||
                      surfaceFormat == SurfaceFormat.Dxt5) &&
                     !device.GLDevice.SupportsS3tc)
            {
                convertedFormat = SurfaceFormat.Color;
            }

            // Check for duplicate instances
            if (existingInstance == null)
            {
                texture = new Texture2D(
                    device,
                    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;
                }

                // Swap the image data if required.
                if (reader.platform == 'x')
                {
                    if (surfaceFormat == SurfaceFormat.Color ||
                        surfaceFormat == SurfaceFormat.ColorBgraEXT)
                    {
                        levelData = X360TexUtil.SwapColor(
                            reader.ReadBytes(levelDataSizeInBytes)
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        levelData = X360TexUtil.SwapDxt1(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        levelData = X360TexUtil.SwapDxt3(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        levelData = X360TexUtil.SwapDxt5(
                            reader.ReadBytes(levelDataSizeInBytes),
                            levelWidth,
                            levelHeight
                            );
                        levelDataSizeInBytes = levelData.Length;
                    }
                }

                // Convert the image data if required
                if (convertedFormat != surfaceFormat)
                {
                    // May already be read in by 'x' conversion
                    if (levelData == null)
                    {
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                    if (surfaceFormat == SurfaceFormat.Dxt1)
                    {
                        levelData = DxtUtil.DecompressDxt1(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt3)
                    {
                        levelData = DxtUtil.DecompressDxt3(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    else if (surfaceFormat == SurfaceFormat.Dxt5)
                    {
                        levelData = DxtUtil.DecompressDxt5(
                            levelData,
                            levelWidth,
                            levelHeight
                            );
                    }
                    levelDataSizeInBytes = levelData.Length;
                }

                int levelDataByteOffset = 0;
                if (levelData == null)
                {
                    if (reader.BaseStream is MemoryStream &&
                        ((MemoryStream)reader.BaseStream).TryGetBuffer(out levelData))
                    {
                        /* Ideally, we didn't have to perform any conversion or
                         * unnecessary reading. Just throw the buffer directly
                         * into SetData, skipping a redundant byte[] copy.
                         */
                        levelDataByteOffset = (int)reader.BaseStream.Seek(0, SeekOrigin.Current);
                        reader.BaseStream.Seek(
                            levelDataSizeInBytes,
                            SeekOrigin.Current
                            );
                    }
                    else
                    {
                        /* If we don't have to perform any conversion and
                         * the ContentReader is not backed by a MemoryStream
                         * with a public buffer, we have to read the data in.
                         */
                        levelData = reader.ReadBytes(levelDataSizeInBytes);
                    }
                }
                texture.SetData(
                    level,
                    null,
                    levelData,
                    levelDataByteOffset,
                    levelDataSizeInBytes
                    );
            }

            return(texture);
        }