Пример #1
0
        protected void CompressMip(DXT1Mip mip, byte[] buffer)
        {
            Debug.Assert(buffer.Length == (mip.Width * mip.Height * srcPixelSize));

            byte[] block = new byte[64];

            int blocksWidth  = mip.Width / 4;
            int blocksHeight = mip.Height / 4;

            int stride  = mip.Width * srcPixelSize;
            int copyLen = 4 * srcPixelSize;

            int dxtOffset = 0;

            for (int y = 0; y < mip.Height; y += 4)
            {
                int lineOffset = y * stride;
                for (int x = 0; x < mip.Width; x += 4)
                {
                    int offset     = lineOffset + x * srcPixelSize;
                    int destOffset = 0;

                    // fill the block with data from the source image
                    for (int line = 0; line < 4; line++)
                    {
                        Buffer.BlockCopy(buffer, offset, block, destOffset, copyLen);
                        offset     += stride;
                        destOffset += copyLen;
                    }
                    CompressBlockDXT1Opaque(block, mip.Buffer, dxtOffset);
                    dxtOffset += 8;
                }
            }
        }
Пример #2
0
        public DXT1Image(Image source)
        {
            // make sure width and height are divisible by 4
            Debug.Assert((source.Width & 0x3) == 0);
            Debug.Assert((source.Height & 0x3) == 0);

            // width and height are powers of 2
            Debug.Assert(isPowerOf2(source.Width));
            Debug.Assert(isPowerOf2(source.Height));

            // only support RGB 24-bit images for now
            //Debug.Assert(source.Format == PixelFormat.R8G8B8);

            // only normal textures
            Debug.Assert(source.NumFaces == 1);
            Debug.Assert(source.NumMipMaps == 1);

            width = source.Width;
            height = source.Height;

            int mipWidth = width;
            int mipHeight = height;
            int mipLevels;

            if (width > height)
            {
                mipLevels = log2(width) - 1;
            }
            else
            {
                mipLevels = log2(height) - 1;
            }

            compressedMips = new DXT1Mip[mipLevels];

            // start by using the source image data for the first iterations.
            // later iterations will use new allocated buffers containing scaled pixels
            byte[] rawBuffer = source.Data;
            for( int mipLevel = 0; mipLevel < mipLevels; mipLevel++)
            {
                compressedMips[mipLevel] = new DXT1Mip(mipWidth, mipHeight);

                //CompressMip(compressedMips[mipLevel], rawBuffer);
                unsafe
                {
                    byte [] outBuffer = compressedMips[mipLevel].Buffer;
                    GCHandle inHandle = GCHandle.Alloc(rawBuffer, GCHandleType.Pinned);
                    GCHandle outHandle = GCHandle.Alloc(outBuffer, GCHandleType.Pinned);
                    IntPtr pIn = inHandle.AddrOfPinnedObject();
                    IntPtr pOut = outHandle.AddrOfPinnedObject();

                    CompressImageDXT1(pIn, pOut, mipWidth, mipHeight);

                    inHandle.Free();
                    outHandle.Free();
                }

                mipWidth = mipWidth / 2;
                mipHeight = mipHeight / 2;

                // create a new uncompressed buffer by scaling the last buffer
                // to the new mip size
                rawBuffer = scaleRawHalfBox(mipWidth, mipHeight, rawBuffer);
            }
        }
Пример #3
0
        protected void CompressMip(DXT1Mip mip, byte[] buffer)
        {
            Debug.Assert(buffer.Length == (mip.Width * mip.Height * srcPixelSize));

            byte[] block = new byte[64];

            int blocksWidth = mip.Width / 4;
            int blocksHeight = mip.Height / 4;

            int stride = mip.Width * srcPixelSize;
            int copyLen = 4 * srcPixelSize;

            int dxtOffset = 0;

            for (int y = 0; y < mip.Height; y += 4)
            {
                int lineOffset = y * stride;
                for (int x = 0; x < mip.Width; x += 4)
                {
                    int offset = lineOffset + x * srcPixelSize;
                    int destOffset = 0;

                    // fill the block with data from the source image
                    for (int line = 0; line < 4; line++)
                    {
                        Buffer.BlockCopy(buffer, offset, block, destOffset, copyLen);
                        offset += stride;
                        destOffset += copyLen;
                    }
                    CompressBlockDXT1Opaque(block, mip.Buffer, dxtOffset);
                    dxtOffset += 8;
                }
            }
        }
Пример #4
0
        public DXT1Image(Image source)
        {
            // make sure width and height are divisible by 4
            Debug.Assert((source.Width & 0x3) == 0);
            Debug.Assert((source.Height & 0x3) == 0);

            // width and height are powers of 2
            Debug.Assert(isPowerOf2(source.Width));
            Debug.Assert(isPowerOf2(source.Height));

            // only support RGB 24-bit images for now
            //Debug.Assert(source.Format == PixelFormat.R8G8B8);

            // only normal textures
            Debug.Assert(source.NumFaces == 1);
            Debug.Assert(source.NumMipMaps == 1);

            width  = source.Width;
            height = source.Height;

            int mipWidth  = width;
            int mipHeight = height;
            int mipLevels;

            if (width > height)
            {
                mipLevels = log2(width) - 1;
            }
            else
            {
                mipLevels = log2(height) - 1;
            }

            compressedMips = new DXT1Mip[mipLevels];

            // start by using the source image data for the first iterations.
            // later iterations will use new allocated buffers containing scaled pixels
            byte[] rawBuffer = source.Data;
            for (int mipLevel = 0; mipLevel < mipLevels; mipLevel++)
            {
                compressedMips[mipLevel] = new DXT1Mip(mipWidth, mipHeight);

                //CompressMip(compressedMips[mipLevel], rawBuffer);
                unsafe
                {
                    byte []  outBuffer = compressedMips[mipLevel].Buffer;
                    GCHandle inHandle  = GCHandle.Alloc(rawBuffer, GCHandleType.Pinned);
                    GCHandle outHandle = GCHandle.Alloc(outBuffer, GCHandleType.Pinned);
                    IntPtr   pIn       = inHandle.AddrOfPinnedObject();
                    IntPtr   pOut      = outHandle.AddrOfPinnedObject();

                    CompressImageDXT1(pIn, pOut, mipWidth, mipHeight);

                    inHandle.Free();
                    outHandle.Free();
                }

                mipWidth  = mipWidth / 2;
                mipHeight = mipHeight / 2;

                // create a new uncompressed buffer by scaling the last buffer
                // to the new mip size
                rawBuffer = scaleRawHalfBox(mipWidth, mipHeight, rawBuffer);
            }
        }