private static TextureContent Compress(Type bitmapContentType, Texture texture, ContentIdentity identity)
    {
      // Let MonoGame's BitmapContent handle the compression.
      var description = texture.Description;
      switch (description.Dimension)
      {
        case TextureDimension.Texture1D:
        case TextureDimension.Texture2D:
          {
            var textureContent = new Texture2DContent { Identity = identity };
            for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
            {
              var image = texture.Images[texture.GetImageIndex(mipIndex, 0, 0)];
              var sourceBitmap = TextureHelper.ToContent(image);
              var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height);
              BitmapContent.Copy(sourceBitmap, targetBitmap);
              textureContent.Mipmaps.Add(targetBitmap);
            }

            return textureContent;
          }
        case TextureDimension.TextureCube:
          {
            var textureContent = new TextureCubeContent { Identity = identity };
            for (int faceIndex = 0; faceIndex < 6; faceIndex++)
            {
              for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
              {
                var image = texture.Images[texture.GetImageIndex(mipIndex, faceIndex, 0)];
                var sourceBitmap = TextureHelper.ToContent(image);
                var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height);
                BitmapContent.Copy(sourceBitmap, targetBitmap);
                textureContent.Faces[faceIndex].Add(targetBitmap);
              }
            }

            return textureContent;
          }
        case TextureDimension.Texture3D:
          {
            var textureContent = new Texture3DContent { Identity = identity };
            for (int zIndex = 0; zIndex < description.Depth; zIndex++)
            {
              textureContent.Faces.Add(new MipmapChain());
              for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
              {
                var image = texture.Images[texture.GetImageIndex(mipIndex, 0, zIndex)];
                var sourceBitmap = TextureHelper.ToContent(image);
                var targetBitmap = (BitmapContent)Activator.CreateInstance(bitmapContentType, image.Width, image.Height);
                BitmapContent.Copy(sourceBitmap, targetBitmap);
                textureContent.Faces[zIndex].Add(targetBitmap);
              }
            }

            return textureContent;
          }
      }

      throw new InvalidOperationException("Invalid texture dimension.");
    }
Example #2
0
        private TextureContent GenerateCubemap(TextureContent input, ContentProcessorContext context)
        {
            if (input.Faces[1].Count != 0)
            {
                //its already a cubemap
                return(base.Process(input, context));
            }
            TextureCubeContent cubeContent = new TextureCubeContent();

            // Convert the input data to Color format, for ease of processing.
            input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));

            int height = input.Faces[0][0].Height;
            int width  = input.Faces[0][0].Width / 6;

            //split the image into 6 pieces, setup: X+,X-, Y+,Y-, Z+, Z-
            cubeContent.Faces[(int)CubeMapFace.PositiveX] = CreateFace(input.Faces[0][0], width, height, 0);
            cubeContent.Faces[(int)CubeMapFace.NegativeX] = CreateFace(input.Faces[0][0], width, height, width * 1);
            cubeContent.Faces[(int)CubeMapFace.PositiveY] = CreateFace(input.Faces[0][0], width, height, width * 2);
            cubeContent.Faces[(int)CubeMapFace.NegativeY] = CreateFace(input.Faces[0][0], width, height, width * 3);
            cubeContent.Faces[(int)CubeMapFace.PositiveZ] = CreateFace(input.Faces[0][0], width, height, width * 4);
            cubeContent.Faces[(int)CubeMapFace.NegativeZ] = CreateFace(input.Faces[0][0], width, height, width * 5);

            // Calculate mipmap data.
            cubeContent.GenerateMipmaps(true);

            // Compress the cubemap into DXT1 format.
            cubeContent.ConvertBitmapType(typeof(Dxt1BitmapContent));
            return(cubeContent);
        }
        /// <summary>
        /// Converts a DigitalRune <see cref="Texture"/> to an XNA <see cref="TextureContent"/>.
        /// </summary>
        /// <param name="texture">The <see cref="Texture"/>.</param>
        /// <param name="identity">The content identity.</param>
        /// <returns>The <see cref="TextureContent"/>.</returns>
        public static TextureContent ToContent(Texture texture, ContentIdentity identity)
        {
            var description = texture.Description;

            switch (description.Dimension)
            {
            case TextureDimension.Texture1D:
            case TextureDimension.Texture2D:
            {
                var textureContent = new Texture2DContent {
                    Identity = identity
                };
                for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
                {
                    var image = texture.Images[texture.GetImageIndex(mipIndex, 0, 0)];
                    textureContent.Mipmaps.Add(ToContent(image));
                }

                return(textureContent);
            }

            case TextureDimension.TextureCube:
            {
                var textureContent = new TextureCubeContent {
                    Identity = identity
                };
                for (int faceIndex = 0; faceIndex < 6; faceIndex++)
                {
                    for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
                    {
                        var image = texture.Images[texture.GetImageIndex(mipIndex, faceIndex, 0)];
                        textureContent.Faces[faceIndex].Add(ToContent(image));
                    }
                }

                return(textureContent);
            }

            case TextureDimension.Texture3D:
            {
                var textureContent = new Texture3DContent {
                    Identity = identity
                };
                for (int zIndex = 0; zIndex < description.Depth; zIndex++)
                {
                    textureContent.Faces.Add(new MipmapChain());
                    for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
                    {
                        var image = texture.Images[texture.GetImageIndex(mipIndex, 0, zIndex)];
                        textureContent.Faces[zIndex].Add(ToContent(image));
                    }
                }

                return(textureContent);
            }
            }

            throw new InvalidOperationException("Invalid texture dimension.");
        }
Example #4
0
        public void TextureCubeContent()
        {
            var content = new TextureCubeContent();

            Assert.NotNull(content.Faces);
            Assert.AreEqual(6, content.Faces.Count);
            Assert.NotNull(content.Faces[0]);
            Assert.NotNull(content.Faces[1]);
            Assert.NotNull(content.Faces[2]);
            Assert.NotNull(content.Faces[3]);
            Assert.NotNull(content.Faces[4]);
            Assert.NotNull(content.Faces[5]);
            Assert.AreEqual(0, content.Faces[0].Count);
            Assert.AreEqual(0, content.Faces[1].Count);
            Assert.AreEqual(0, content.Faces[2].Count);
            Assert.AreEqual(0, content.Faces[3].Count);
            Assert.AreEqual(0, content.Faces[4].Count);
            Assert.AreEqual(0, content.Faces[5].Count);

            var face0 = new MipmapChain(new PixelBitmapContent <Color>(2, 2));

            content.Faces[0] = face0;
            Assert.AreEqual(face0, content.Faces[0]);
            Assert.AreEqual(1, content.Faces[0].Count);

            content.Faces[0].Add(new PixelBitmapContent <Color>(1, 1));
            Assert.AreEqual(2, content.Faces[0].Count);

            content.Faces[1].Add(new PixelBitmapContent <Color>(2, 2));
            content.Faces[2].Add(new PixelBitmapContent <Color>(2, 2));
            content.Faces[3].Add(new PixelBitmapContent <Color>(2, 2));
            content.Faces[4].Add(new PixelBitmapContent <Color>(2, 2));
            content.Faces[5].Add(new PixelBitmapContent <Color>(2, 2));
            Assert.AreEqual(1, content.Faces[1].Count);
            Assert.AreEqual(1, content.Faces[2].Count);
            Assert.AreEqual(1, content.Faces[3].Count);
            Assert.AreEqual(1, content.Faces[4].Count);
            Assert.AreEqual(1, content.Faces[5].Count);

            Assert.Throws <NotSupportedException>(() => content.Faces.Clear());
            Assert.Throws <NotSupportedException>(() => content.Faces.RemoveAt(0));
            Assert.Throws <NotSupportedException>(() => content.Faces.Add(new MipmapChain()));
            Assert.Throws <NotSupportedException>(() => content.Faces.Insert(0, new MipmapChain()));
            Assert.Throws <NotSupportedException>(() => content.Faces.Remove(content.Faces[0]));
        }
Example #5
0
        internal static TextureContent Import(string filename, ContentImporterContext context)
        {
            var            identity = new ContentIdentity(filename);
            TextureContent output   = null;

            using (var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read))
                using (var reader = new BinaryReader(fileStream))
                {
                    // Signature ("DDS ")
                    if (reader.ReadByte() != 0x44 ||
                        reader.ReadByte() != 0x44 ||
                        reader.ReadByte() != 0x53 ||
                        reader.ReadByte() != 0x20)
                    {
                        throw new ContentLoadException("Invalid file signature");
                    }

                    var header = new DdsHeader
                    {
                        // Read DDS_HEADER
                        dwSize = reader.ReadUInt32()
                    };

                    if (header.dwSize != 124)
                    {
                        throw new ContentLoadException("Invalid DDS_HEADER dwSize value");
                    }

                    header.dwFlags             = (Ddsd)reader.ReadUInt32();
                    header.dwHeight            = reader.ReadUInt32();
                    header.dwWidth             = reader.ReadUInt32();
                    header.dwPitchOrLinearSize = reader.ReadUInt32();
                    header.dwDepth             = reader.ReadUInt32();
                    header.dwMipMapCount       = reader.ReadUInt32();
                    // The next 11 DWORDs are reserved and unused
                    for (int i = 0; i < 11; ++i)
                    {
                        reader.ReadUInt32();
                    }

                    // Read DDS_PIXELFORMAT
                    header.ddspf.dwSize = reader.ReadUInt32();
                    if (header.ddspf.dwSize != 32)
                    {
                        throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value");
                    }

                    header.ddspf.dwFlags       = (Ddpf)reader.ReadUInt32();
                    header.ddspf.dwFourCC      = (FourCC)reader.ReadUInt32();
                    header.ddspf.dwRgbBitCount = reader.ReadUInt32();
                    header.ddspf.dwRBitMask    = reader.ReadUInt32();
                    header.ddspf.dwGBitMask    = reader.ReadUInt32();
                    header.ddspf.dwBBitMask    = reader.ReadUInt32();
                    header.ddspf.dwABitMask    = reader.ReadUInt32();

                    // Continue reading DDS_HEADER
                    header.dwCaps  = (DdsCaps)reader.ReadUInt32();
                    header.dwCaps2 = (DdsCaps2)reader.ReadUInt32();

                    reader.ReadUInt32(); // dwCaps3 unused
                    reader.ReadUInt32(); // dwCaps4 unused
                    reader.ReadUInt32(); // dwReserved2 unused

                    // Check for the existence of the DDS_HEADER_DXT10 struct next
                    if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10)
                    {
                        throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found");
                    }

                    int faceCount   = 1;
                    int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1);
                    if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap))
                    {
                        if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces))
                        {
                            throw new ContentLoadException("Incomplete cubemap in DDS file");
                        }
                        faceCount = 6;
                        output    = new TextureCubeContent()
                        {
                            Identity = identity
                        };
                    }
                    else
                    {
                        output = new Texture2DContent()
                        {
                            Identity = identity
                        };
                    }

                    var format = GetSurfaceFormat(ref header.ddspf, out bool rbSwap);

                    for (int f = 0; f < faceCount; ++f)
                    {
                        int w       = (int)header.dwWidth;
                        int h       = (int)header.dwHeight;
                        var mipMaps = new MipmapChain();
                        for (int m = 0; m < mipMapCount; ++m)
                        {
                            var content   = CreateBitmapContent(format, w, h);
                            var byteCount = GetBitmapSize(format, w, h);
                            // A 24-bit format is slightly different
                            if (header.ddspf.dwRgbBitCount == 24)
                            {
                                byteCount = 3 * w * h;
                            }

                            var bytes = reader.ReadBytes(byteCount);
                            if (rbSwap)
                            {
                                switch (format)
                                {
                                case SurfaceFormat.Bgr565:
                                    ByteSwapBGR565(bytes);
                                    break;

                                case SurfaceFormat.Bgra4444:
                                    ByteSwapBGRA4444(bytes);
                                    break;

                                case SurfaceFormat.Bgra5551:
                                    ByteSwapBGRA5551(bytes);
                                    break;

                                case SurfaceFormat.Rgba32:
                                    if (header.ddspf.dwRgbBitCount == 32)
                                    {
                                        ByteSwapRGBX(bytes);
                                    }
                                    else if (header.ddspf.dwRgbBitCount == 24)
                                    {
                                        ByteSwapRGB(bytes);
                                    }
                                    break;
                                }
                            }
                            if ((format == SurfaceFormat.Rgba32) &&
                                header.ddspf.dwFlags.HasFlag(Ddpf.Rgb) &&
                                !header.ddspf.dwFlags.HasFlag(Ddpf.AlphaPixels))
                            {
                                // Fill or add alpha with opaque
                                if (header.ddspf.dwRgbBitCount == 32)
                                {
                                    ByteFillAlpha(bytes);
                                }
                                else if (header.ddspf.dwRgbBitCount == 24)
                                {
                                    ByteExpandAlpha(ref bytes);
                                }
                            }
                            content.SetPixelData(bytes);
                            mipMaps.Add(content);
                            w = Math.Max(1, w / 2);
                            h = Math.Max(1, h / 2);
                        }
                        output.Faces[f] = mipMaps;
                    }
                }

            return(output);
        }
Example #6
0
        static internal TextureContent Import(string filename, ContentImporterContext context)
        {
            var            identity = new ContentIdentity(filename);
            TextureContent output   = null;

            using (var reader = new BinaryReader(new FileStream(filename, FileMode.Open, FileAccess.Read)))
            {
                // Read signature ("DDS ")
                var valid = reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x44;
                valid = valid && reader.ReadByte() == 0x53;
                valid = valid && reader.ReadByte() == 0x20;
                if (!valid)
                {
                    throw new ContentLoadException("Invalid file signature");
                }

                var header = new DdsHeader();

                // Read DDS_HEADER
                header.dwSize = reader.ReadUInt32();
                if (header.dwSize != 124)
                {
                    throw new ContentLoadException("Invalid DDS_HEADER dwSize value");
                }
                header.dwFlags             = (Ddsd)reader.ReadUInt32();
                header.dwHeight            = reader.ReadUInt32();
                header.dwWidth             = reader.ReadUInt32();
                header.dwPitchOrLinearSize = reader.ReadUInt32();
                header.dwDepth             = reader.ReadUInt32();
                header.dwMipMapCount       = reader.ReadUInt32();
                // The next 11 DWORDs are reserved and unused
                for (int i = 0; i < 11; ++i)
                {
                    reader.ReadUInt32();
                }
                // Read DDS_PIXELFORMAT
                header.ddspf.dwSize = reader.ReadUInt32();
                if (header.ddspf.dwSize != 32)
                {
                    throw new ContentLoadException("Invalid DDS_PIXELFORMAT dwSize value");
                }
                header.ddspf.dwFlags       = (Ddpf)reader.ReadUInt32();
                header.ddspf.dwFourCC      = (FourCC)reader.ReadUInt32();
                header.ddspf.dwRgbBitCount = reader.ReadUInt32();
                header.ddspf.dwRBitMask    = reader.ReadUInt32();
                header.ddspf.dwGBitMask    = reader.ReadUInt32();
                header.ddspf.dwBBitMask    = reader.ReadUInt32();
                header.ddspf.dwABitMask    = reader.ReadUInt32();
                // Continue reading DDS_HEADER
                header.dwCaps  = (DdsCaps)reader.ReadUInt32();
                header.dwCaps2 = (DdsCaps2)reader.ReadUInt32();
                // dwCaps3 unused
                reader.ReadUInt32();
                // dwCaps4 unused
                reader.ReadUInt32();
                // dwReserved2 unused
                reader.ReadUInt32();

                // Check for the existence of the DDS_HEADER_DXT10 struct next
                if (header.ddspf.dwFlags == Ddpf.FourCC && header.ddspf.dwFourCC == FourCC.Dx10)
                {
                    throw new ContentLoadException("Unsupported DDS_HEADER_DXT10 struct found");
                }

                int faceCount   = 1;
                int mipMapCount = (int)(header.dwCaps.HasFlag(DdsCaps.MipMap) ? header.dwMipMapCount : 1);
                if (header.dwCaps.HasFlag(DdsCaps.Complex))
                {
                    if (header.dwCaps2.HasFlag(DdsCaps2.Cubemap))
                    {
                        if (!header.dwCaps2.HasFlag(DdsCaps2.CubemapAllFaces))
                        {
                            throw new ContentLoadException("Incomplete cubemap in DDS file");
                        }
                        faceCount = 6;
                        output    = new TextureCubeContent()
                        {
                            Identity = identity
                        };
                    }
                    else
                    {
                        output = new Texture2DContent()
                        {
                            Identity = identity
                        };
                    }
                }
                else
                {
                    output = new Texture2DContent()
                    {
                        Identity = identity
                    };
                }

                bool rbSwap;
                var  format = GetSurfaceFormat(ref header.ddspf, out rbSwap);

                for (int f = 0; f < faceCount; ++f)
                {
                    var w       = (int)header.dwWidth;
                    var h       = (int)header.dwHeight;
                    var mipMaps = new MipmapChain();
                    for (int m = 0; m < mipMapCount; ++m)
                    {
                        var content   = CreateBitmapContent(format, w, h);
                        var byteCount = GetBitmapSize(format, w, h);
                        var bytes     = reader.ReadBytes(byteCount);
                        content.SetPixelData(bytes);
                        mipMaps.Add(content);
                        w = MathHelper.Max(1, w / 2);
                        h = MathHelper.Max(1, h / 2);
                    }
                    output.Faces[f] = mipMaps;
                }
            }

            return(output);
        }
Example #7
0
        private TextureCubeContent ImportCubeTexture(FIBITMAP bitmap, ImageType imageType, ContentManager manager)
        {
            TextureCubeContent content = new TextureCubeContent();

            if (CubeFaces == null || CubeFaces.Length == 0)
            {
                int width  = (int)FreeImage.GetWidth(bitmap);
                int height = (int)FreeImage.GetHeight(bitmap);
                // image is a cube cross
                if (width > height) // horizontal cross
                {
                    width  = width / 4;
                    height = height / 3;
                    // +x
                    content.Faces[0][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width * 2, height, width * 3, height * 2));
                    // -x
                    content.Faces[1][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, 0, height, width, height * 2));
                    // +y
                    content.Faces[2][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, 0, width * 2, height));
                    // -y
                    content.Faces[3][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, height * 2, width * 2, height * 3));
                    // +z
                    content.Faces[4][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, height, width * 2, height * 2));
                    // -z
                    content.Faces[5][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width * 3, height, width * 4, height * 2));
                }
                else // vertical cross
                {
                    width  = width / 3;
                    height = height / 4;
                    // +x
                    content.Faces[0][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width * 2, height, width * 3, height * 2));
                    // -x
                    content.Faces[1][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, 0, height, width, height * 2));
                    // +y
                    content.Faces[2][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, 0, width * 2, height));
                    // -y
                    content.Faces[3][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, height * 2, width * 2, height * 3));
                    // +z
                    content.Faces[4][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, height, width * 2, height * 2));
                    // -z
                    content.Faces[5][0] = new BitmapContent(width, height, imageType, FreeImage.Copy(bitmap, width, height * 3, width * 2, height * 4));
                }
            }
            else
            {
                int width  = (int)FreeImage.GetWidth(bitmap);
                int height = (int)FreeImage.GetHeight(bitmap);

                try
                {
                    // main image file is +x and CubeFaces contains images for [-x, +y, -y, +z, -z]
                    content.Faces[0][0] = new BitmapContent(width, height, imageType, bitmap);
                    FIBITMAP bitmap2 = FreeImage.LoadEx(CubeFaces[0]);    // -x
                    content.Faces[1][0] = new BitmapContent(width, height, imageType, bitmap2);
                    bitmap2             = FreeImage.LoadEx(CubeFaces[1]); // +y
                    content.Faces[2][0] = new BitmapContent(width, height, imageType, bitmap2);
                    bitmap2             = FreeImage.LoadEx(CubeFaces[2]); // -y
                    content.Faces[3][0] = new BitmapContent(width, height, imageType, bitmap2);
                    bitmap2             = FreeImage.LoadEx(CubeFaces[3]); // +z
                    content.Faces[4][0] = new BitmapContent(width, height, imageType, bitmap2);
                    bitmap2             = FreeImage.LoadEx(CubeFaces[4]); // -z
                    content.Faces[5][0] = new BitmapContent(width, height, imageType, bitmap2);
                }
                catch (Exception)
                {
                    manager.Log.Error("Error loading cubemap files.");
                    content = null;
                }
            }

            return(content);
        }
Example #8
0
        public override TextureContent Import(string filename, ContentImporterContext context)
        {
            TextureContent output;

            using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (var reader = new BinaryReader(stream))
                {
                    var header = new DDSHeader(reader);
                    if (header.PixelFormat.Flags == PF_Flags.FOURCC && header.PixelFormat.FourCC == PF_FourCC.DX10)
                    {
                        throw new NotImplementedException("DX10 Header not supported");
                    }
                    if (header.PitchOrLinearSize != 0)
                    {
                        throw new NotImplementedException();
                    }


                    if (header.Caps2.HasFlag(DDS_Caps2.CUBEMAP))
                    {
                        var cube   = new TextureCubeContent();
                        var format = GetFormat(header.PixelFormat);
                        for (int f = 0; f < 6; f++)
                        {
                            var           width  = header.Width;
                            var           height = header.Height;
                            BitmapContent bitmap = CreateBitmap(format, width, height);
                            var           size   = GetBitmapSize(format, width, height);
                            byte[]        src    = reader.ReadBytes(size);
                            bitmap.SetPixelData(src);
                            cube.Faces[f].Add(bitmap);

                            if (header.Caps.HasFlag(DDS_Caps.MIPMAP))
                            {
                                for (int m = 0; m < header.MipMapCount - 1; m++)
                                {
                                    width  = width / 2;
                                    height = height / 2;

                                    bitmap = CreateBitmap(format, width, height);
                                    size   = GetBitmapSize(format, width, height);
                                    src    = reader.ReadBytes(size);
                                    bitmap.SetPixelData(src);
                                    cube.Faces[f].Add(bitmap);
                                }
                            }
                        }
                        output = cube;
                    }
                    else
                    {
                        throw new NotImplementedException(header.Caps2 + " not supported");
                    }

                    reader.Close();
                    stream.Close();
                }
            }

            return(output);
        }