Exemplo n.º 1
0
        /// <summary>
        /// Given a block, extract the colour information and convert to 5554 formats
        /// </summary>
        private void Unpack5554Colour(AmtcBlock block, int[,] abColors)
        {
            // extract A and B
            // 15 bits (shifted up by one)
            m_rawBits[0] = block.PackedData1 & (0xFFFE);
            // 16 bits
            m_rawBits[1] = block.PackedData1 >> 16;

            // step through both colours
            for (int i = 0; i < 2; i++)
            {
                // if completely opaque
                if ((m_rawBits[i] & (1 << 15)) != 0)
                {
                    // extract R and G (both 5 bit)
                    abColors[i, 0] = (int)((m_rawBits[i] >> 10) & 0x1F);
                    abColors[i, 1] = (int)((m_rawBits[i] >> 5) & 0x1F);

                    // The precision of Blue depends on  A or B. If A then we need to replicate the top bit to get 5 bits in total
                    abColors[i, 2] = (int)(m_rawBits[i] & 0x1F);
                    if (i == 0)
                    {
                        abColors[0, 2] |= abColors[0, 2] >> 4;
                    }

                    // set 4bit alpha fully on...
                    abColors[i, 3] = 0xF;
                }
                // else if colour has variable translucency
                else
                {
                    // extract R and G (both 4 bit). Leave a space on the end for the replication of bits
                    abColors[i, 0] = (int)((m_rawBits[i] >> (8 - 1)) & 0x1E);
                    abColors[i, 1] = (int)((m_rawBits[i] >> (4 - 1)) & 0x1E);

                    // replicate bits to truly expand to 5 bits
                    abColors[i, 0] |= abColors[i, 0] >> 4;
                    abColors[i, 1] |= abColors[i, 1] >> 4;

                    // grab the 3(+padding) or 4 bits of blue and add an extra padding bit
                    abColors[i, 2] = (int)((m_rawBits[i] & 0xF) << 1);

                    // expand from 3 to 5 bits if this is from colour A, or 4 to 5 bits if from colour B
                    if (i == 0)
                    {
                        abColors[0, 2] |= abColors[0, 2] >> 3;
                    }
                    else
                    {
                        abColors[0, 2] |= abColors[0, 2] >> 4;
                    }

                    // set the alpha bits to be 3 + a zero on the end
                    abColors[i, 3] = (int)((m_rawBits[i] >> 11) & 0xE);
                }
            }
        }
Exemplo n.º 2
0
 private static AmtcBlock[] GenerateBlocks(byte[] input)
 {
     AmtcBlock[] blocks = new AmtcBlock[input.Length / 8];
     using (MemoryStream ms = new MemoryStream(input))
     {
         using (BinaryReader reader = new BinaryReader(ms))
         {
             int i = 0;
             while (reader.BaseStream.Position != reader.BaseStream.Length)
             {
                 uint      v0    = reader.ReadUInt32();
                 uint      v1    = reader.ReadUInt32();
                 AmtcBlock block = new AmtcBlock(v0, v1);
                 blocks[i++] = block;
             }
         }
     }
     return(blocks);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Given the block and the texture type and it's relative position in the 2x2 group of blocks, extract the bit patterns for the fully defined pixels.
        /// </summary>
        private static void UnpackModulations(AmtcBlock block, bool do2bitMode, int[,] modulationVals, int[,] modulationModes, int startX, int startY)
        {
            int  blockModMode   = (int)(block.PackedData1 & 1);
            uint modulationBits = block.PackedData0;

            // if it's in an interpolated mode
            if (do2bitMode && (blockModMode != 0))
            {
                // run through all the pixels in the block. Note we can now treat all the "stored" values as if they have 2bits (even when they didn't!)
                for (int y = 0; y < BlockYSize; y++)
                {
                    for (int x = 0; x < BlockX2bpp; x++)
                    {
                        modulationModes[y + startY, x + startX] = blockModMode;

                        // if this is a stored value...
                        if (((x ^ y) & 1) == 0)
                        {
                            modulationVals[y + startY, x + startX] = (int)(modulationBits & 3);
                            modulationBits >>= 2;
                        }
                    }
                }
            }
            // else if direct encoded 2bit mode - i.e. 1 mode bit per pixel
            else if (do2bitMode)
            {
                for (int y = 0; y < BlockYSize; y++)
                {
                    for (int x = 0; x < BlockX2bpp; x++)
                    {
                        modulationModes[y + startY, x + startX] = blockModMode;

                        // double the bits so 0=> 00, and 1=>11
                        if ((modulationBits & 1) != 0)
                        {
                            modulationVals[y + startY, x + startX] = 0x3;
                        }
                        else
                        {
                            modulationVals[y + startY, x + startX] = 0x0;
                        }
                        modulationBits >>= 1;
                    }
                }
            }
            // else its the 4bpp mode so each value has 2 bits
            else
            {
                for (int y = 0; y < BlockYSize; y++)
                {
                    for (int x = 0; x < BlockX4bpp; x++)
                    {
                        modulationModes[y + startY, x + startX] = blockModMode;

                        modulationVals[y + startY, x + startX] = (int)(modulationBits & 3);
                        modulationBits >>= 2;
                    }
                }
            }

            // make sure nothing is left over
            if (modulationBits != 0)
            {
                throw new Exception("Something is left over");
            }
        }