Exemple #1
0
        protected bool writeData(IntPtr data, int length)
        {
            var dataBuffer = new byte[length];

            Marshal.Copy(data, dataBuffer, 0, length);

            DxtBitmapContent texContent = null;
            switch (_format)
            {
                case Format.DXT1:
                    texContent = new Dxt1BitmapContent(_levelWidth, _levelHeight);
                    break;
                case Format.DXT3:
                    texContent = new Dxt3BitmapContent(_levelWidth, _levelHeight);
                    break;
                case Format.DXT5:
                    texContent = new Dxt5BitmapContent(_levelWidth, _levelHeight);
                    break;
            }

            if (_content.Faces[0].Count == _currentMipLevel)
                _content.Faces[0].Add(texContent);
            else
                _content.Faces[0][_currentMipLevel] = texContent;

            _content.Faces[0][_currentMipLevel].SetPixelData(dataBuffer);

            return true;
        }
        /// <summary>
        /// 指定された単色ビットマップ画像をDXT3テクスチャへ変換する
        /// </summary>
        /// <param name="source">変換元画像</param>
        /// <param name="color0">単色カラー</param>
        /// <returns>DXT3圧縮された画像</returns>
        public static Dxt3BitmapContent Compress(PixelBitmapContent<Color> source,
                                                    Color color0)
        {
            // DXT3ブロックデータを格納するためのバッファを確保
            byte[] outputData = new byte[source.Width * source.Height];

            // 単色カラーをBGR565に変換する
            ushort packedColor = new Bgr565(color0.ToVector3()).PackedValue;

            // 指定された画像を圧縮ブロック単位に処理をする
            int outputIndex = 0;
            for (int blockY = 0; blockY < source.Height; blockY += 4)
            {
                for (int blockX = 0; blockX < source.Width; blockX += 4)
                {
                    CompressDxt3Block(source, blockX, blockY, packedColor,
                                        outputData, outputIndex);
                    outputIndex += 16;
                }
            }

            // DXT3テクスチャの生成と圧縮したブロックデータの設定
            var result = new Dxt3BitmapContent(source.Width, source.Height);
            result.SetPixelData(outputData);

            return result;
        }
Exemple #3
0
        protected bool writeData(IntPtr data, int length)
        {
            var dataBuffer = new byte[length];

            Marshal.Copy(data, dataBuffer, 0, length);

            DxtBitmapContent texContent = null;

            switch (_format)
            {
            case Format.DXT1:
                texContent = new Dxt1BitmapContent(_levelWidth, _levelHeight);
                break;

            case Format.DXT3:
                texContent = new Dxt3BitmapContent(_levelWidth, _levelHeight);
                break;

            case Format.DXT5:
                texContent = new Dxt5BitmapContent(_levelWidth, _levelHeight);
                break;
            }

            if (_content.Faces[0].Count == _currentMipLevel)
            {
                _content.Faces[0].Add(texContent);
            }
            else
            {
                _content.Faces[0][_currentMipLevel] = texContent;
            }

            _content.Faces[0][_currentMipLevel].SetPixelData(dataBuffer);

            return(true);
        }
        // Compress the greyscale font texture page using a specially-formulated DXT3 mode
        static public unsafe void CompressFontDXT3(TextureContent content)
        {
            if (content.Faces.Count > 1)
            {
                throw new PipelineException("Font textures should only have one face");
            }

            var block = new Vector4[16];

            for (int i = 0; i < content.Faces[0].Count; ++i)
            {
                var face     = content.Faces[0][i];
                var xBlocks  = (face.Width + 3) / 4;
                var yBlocks  = (face.Height + 3) / 4;
                var dxt3Size = xBlocks * yBlocks * 16;
                var buffer   = new byte[dxt3Size];

                var bytes = face.GetPixelData();
                fixed(byte *b = bytes)
                {
                    Vector4 *colors = (Vector4 *)b;

                    int w = 0;
                    int h = 0;
                    int x = 0;
                    int y = 0;

                    while (h < (face.Height & ~3))
                    {
                        w = 0;
                        x = 0;

                        var h0 = h * face.Width;
                        var h1 = h0 + face.Width;
                        var h2 = h1 + face.Width;
                        var h3 = h2 + face.Width;

                        while (w < (face.Width & ~3))
                        {
                            block[0]  = colors[w + h0];
                            block[1]  = colors[w + h0 + 1];
                            block[2]  = colors[w + h0 + 2];
                            block[3]  = colors[w + h0 + 3];
                            block[4]  = colors[w + h1];
                            block[5]  = colors[w + h1 + 1];
                            block[6]  = colors[w + h1 + 2];
                            block[7]  = colors[w + h1 + 3];
                            block[8]  = colors[w + h2];
                            block[9]  = colors[w + h2 + 1];
                            block[10] = colors[w + h2 + 2];
                            block[11] = colors[w + h2 + 3];
                            block[12] = colors[w + h3];
                            block[13] = colors[w + h3 + 1];
                            block[14] = colors[w + h3 + 2];
                            block[15] = colors[w + h3 + 3];

                            int offset = (x + y * xBlocks) * 16;
                            CompressFontDXT3Block(block, buffer, offset);

                            w += 4;
                            ++x;
                        }

                        // Do partial block at end of row
                        if (w < face.Width)
                        {
                            var cols = face.Width - w;
                            Array.Clear(block, 0, 16);
                            for (int r = 0; r < 4; ++r)
                            {
                                h0 = (h + r) * face.Width;
                                for (int c = 0; c < cols; ++c)
                                {
                                    block[(r * 4) + c] = colors[w + h0 + c];
                                }
                            }

                            int offset = (x + y * xBlocks) * 16;
                            CompressFontDXT3Block(block, buffer, offset);
                        }

                        h += 4;
                        ++y;
                    }

                    // Do last partial row
                    if (h < face.Height)
                    {
                        var rows = face.Height - h;
                        w = 0;
                        x = 0;
                        while (w < (face.Width & ~3))
                        {
                            Array.Clear(block, 0, 16);
                            for (int r = 0; r < rows; ++r)
                            {
                                var h0 = (h + r) * face.Width;
                                block[(r * 4) + 0] = colors[w + h0 + 0];
                                block[(r * 4) + 1] = colors[w + h0 + 1];
                                block[(r * 4) + 2] = colors[w + h0 + 2];
                                block[(r * 4) + 3] = colors[w + h0 + 3];
                            }

                            int offset = (x + y * xBlocks) * 16;
                            CompressFontDXT3Block(block, buffer, offset);

                            w += 4;
                            ++x;
                        }

                        // Do last partial block
                        if (w < face.Width)
                        {
                            var cols = face.Width - w;
                            Array.Clear(block, 0, 16);
                            for (int r = 0; r < rows; ++r)
                            {
                                var h0 = (h + r) * face.Width;
                                for (int c = 0; c < cols; ++c)
                                {
                                    block[(r * 4) + c] = colors[w + h0 + c];
                                }
                            }

                            int offset = (x + y * xBlocks) * 16;
                            CompressFontDXT3Block(block, buffer, offset);
                        }
                    }
                }

                var dxt3 = new Dxt3BitmapContent(face.Width, face.Height);
                dxt3.SetPixelData(buffer);
                content.Faces[0][i] = dxt3;
            }
        }
        /// <summary>
        /// Converts a DigitalRune <see cref="Image"/> to an XNA <see cref="BitmapContent"/>.
        /// </summary>
        /// <param name="image">The <see cref="Image"/>.</param>
        /// <returns>The <see cref="BitmapContent"/>.</returns>
        public static BitmapContent ToContent(Image image)
        {
            BitmapContent content;
              switch (image.Format)
              {
            case DataFormat.R8G8B8A8_UNORM:
            case DataFormat.R8G8B8A8_UNORM_SRGB:
              content = new PixelBitmapContent<Color>(image.Width, image.Height);
              break;
            case DataFormat.B5G6R5_UNORM:
              content = new PixelBitmapContent<Bgr565>(image.Width, image.Height);
              break;
            #if !MONOGAME
            case DataFormat.B5G5R5A1_UNORM:
              content = new PixelBitmapContent<Bgra5551>(image.Width, image.Height);
              break;
            #endif
            case DataFormat.B4G4R4A4_UNORM:
              content = new PixelBitmapContent<Bgra4444>(image.Width, image.Height);
              break;
            case DataFormat.BC1_UNORM:
            case DataFormat.BC1_UNORM_SRGB:
              content = new Dxt1BitmapContent(image.Width, image.Height);
              break;
            case DataFormat.BC2_UNORM:
            case DataFormat.BC2_UNORM_SRGB:
              content = new Dxt3BitmapContent(image.Width, image.Height);
              break;
            case DataFormat.BC3_UNORM:
            case DataFormat.BC3_UNORM_SRGB:
            content = new Dxt5BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.R8G8_SNORM:
            content = new PixelBitmapContent<NormalizedByte2>(image.Width, image.Height);
            break;
            case DataFormat.R8G8B8A8_SNORM:
            content = new PixelBitmapContent<NormalizedByte4>(image.Width, image.Height);
            break;
            #if !MONOGAME
            case DataFormat.R10G10B10A2_UNORM:
              content = new PixelBitmapContent<Rgba1010102>(image.Width, image.Height);
              break;
            case DataFormat.R16G16_UNORM:
              content = new PixelBitmapContent<Rg32>(image.Width, image.Height);
              break;
            case DataFormat.R16G16B16A16_UNORM:
              content = new PixelBitmapContent<Rgba64>(image.Width, image.Height);
              break;
            case DataFormat.A8_UNORM:
            case DataFormat.R8_UNORM:
              content = new PixelBitmapContent<Alpha8>(image.Width, image.Height);
              break;
            #endif
            case DataFormat.R32_FLOAT:
            content = new PixelBitmapContent<float>(image.Width, image.Height);
            break;
            case DataFormat.R32G32_FLOAT:
            content = new PixelBitmapContent<Vector2>(image.Width, image.Height);
            break;
            case DataFormat.R32G32B32A32_FLOAT:
            content = new PixelBitmapContent<Vector4>(image.Width, image.Height);
            break;
            case DataFormat.R16_FLOAT:
            content = new PixelBitmapContent<HalfSingle>(image.Width, image.Height);
            break;
            case DataFormat.R16G16_FLOAT:
            content = new PixelBitmapContent<HalfVector2>(image.Width, image.Height);
            break;
            case DataFormat.R16G16B16A16_FLOAT:
            content = new PixelBitmapContent<HalfVector4>(image.Width, image.Height);
            break;
            #if MONOGAME
            case DataFormat.PVRTCI_2bpp_RGB:
            content = new PvrtcRgb2BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_4bpp_RGB:
            content = new PvrtcRgb4BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_2bpp_RGBA:
            content = new PvrtcRgba2BitmapContent(image.Width, image.Height);
            break;
            case DataFormat.PVRTCI_4bpp_RGBA:
            content = new PvrtcRgba4BitmapContent(image.Width, image.Height);
            break;

            case DataFormat.ETC1:
            content = new Etc1BitmapContent(image.Width, image.Height);
            break;

            //case DataFormat.ATC_RGB: Not supported in MonoGame.
            case DataFormat.ATC_RGBA_EXPLICIT_ALPHA:
            content = new AtcExplicitBitmapContent(image.Width, image.Height);
            break;
            case DataFormat.ATC_RGBA_INTERPOLATED_ALPHA:
            content = new AtcInterpolatedBitmapContent(image.Width, image.Height);
            break;
            #endif

            default:
              string message = string.Format("The texture format {0} is not supported in MonoGame.", image.Format);
              throw new NotSupportedException(message);

            // Not supported:
            //  SurfaceFormat.HdrBlendable  // Only needed as render target format.
            //  SurfaceFormat.Bgr32         // Only used as WPF render target.
            //  SurfaceFormat.Bgra32        // Only used as WPF render target.
            //  SurfaceFormat.Dxt1a
              }

              Debug.Assert(content != null);
            #if !MONOGAME
              // content.GetPixelData() is null in MonoGame.
              Debug.Assert(image.Data.Length == content.GetPixelData().Length);
            #endif

              content.SetPixelData(image.Data);
              return content;
        }