Example #1
0
        /// <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;
        }
Example #2
0
        // 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;
            }
        }