示例#1
0
        private static void selectDiagonal(Vector3 *points, int num, Vector3 *maxColor, Vector3 *minColor)
        {
            Vector3  center = (*maxColor + *minColor) * 0.5f;
            Vector3  t;
            Vector2 *tp = (Vector2 *)&t;

            Vector2 covariance = new Vector2();

            for (uint i = 0; i < num; i++)
            {
                t           = points[i] - center;
                covariance += *tp * t._z;
            }

            float x0 = maxColor->_x;
            float y0 = maxColor->_y;
            float x1 = minColor->_x;
            float y1 = minColor->_y;

            if (covariance._x < 0)
            {
                VoidPtr.Swap(&x0, &x1);
            }

            if (covariance._y < 0)
            {
                VoidPtr.Swap(&y0, &y1);
            }

            maxColor->_x = x0;
            maxColor->_y = y0;

            minColor->_x = x1;
            minColor->_y = y1;
        }
示例#2
0
        private static void optimizeEndPoints4(Vector3 *points, CMPRBlock *block)
        {
            float   alpha2_sum    = 0.0f;
            float   beta2_sum     = 0.0f;
            float   alphabeta_sum = 0.0f;
            Vector3 alphax_sum    = new Vector3();
            Vector3 betax_sum     = new Vector3();
            uint    indices       = block->_lookup;

            for (int i = 0, bi = 30; i < 16; ++i, bi -= 2)
            {
                uint bits = indices >> bi;

                float beta = bits & 1;
                if ((bits & 2) != 0)
                {
                    beta = (1 + beta) / 3.0f;
                }

                float alpha = 1.0f - beta;

                alpha2_sum    += alpha * alpha;
                beta2_sum     += beta * beta;
                alphabeta_sum += alpha * beta;
                alphax_sum    += alpha * points[i];
                betax_sum     += beta * points[i];
            }

            float denom = alpha2_sum * beta2_sum - alphabeta_sum * alphabeta_sum;

            if (Math.Abs(denom) <= 0.0001f)
            {
                return;
            }

            float factor = 1.0f / denom;

            Vector3 a = (alphax_sum * beta2_sum - betax_sum * alphabeta_sum) * factor;
            Vector3 b = (betax_sum * alpha2_sum - alphax_sum * alphabeta_sum) * factor;

            a.Clamp(0.0f, 255.0f);
            b.Clamp(0.0f, 255.0f);

            ushort color0 = roundAndExpand(&a);
            ushort color1 = roundAndExpand(&b);

            if (color0 < color1)
            {
                Vector3 t = a;
                a = b;
                b = t;
                VoidPtr.Swap(&color0, &color1);
            }

            //CMPRBlock block = new CMPRBlock();
            block->_root0._data = color0;
            block->_root1._data = color1;
            block->_lookup      = computeIndices4(points, &a, &b);
        }
示例#3
0
        private static CMPRBlock optimalCompressDXT1(ARGBPixel c)
        {
            CMPRBlock block = new CMPRBlock();

            uint indices = 0xAAAAAAAA;

            block._root0._data = (ushort)((OMatch5[c.R, 0] << 11) | (OMatch6[c.G, 0] << 5) | OMatch5[c.B, 0]);
            block._root1._data = (ushort)((OMatch5[c.R, 1] << 11) | (OMatch6[c.G, 1] << 5) | OMatch5[c.B, 1]);

            if (block._root0 < block._root1)
            {
                VoidPtr.Swap((short *)&block._root0, (short *)&block._root1);
                indices ^= 0x55555555;
            }
            block._lookup = indices;
            return(block);
        }
示例#4
0
        private static CMPRBlock compressDXT1(ARGBPixel *pBlock)
        {
            float *  pointData = stackalloc float[48];
            Vector3 *points    = (Vector3 *)pointData;

            extractColorBlockRGB(pBlock, points);

            // find min and max colors
            Vector3 maxColor, minColor;

            findMinMaxColorsBox(points, 16, &maxColor, &minColor);

            selectDiagonal(points, 16, &maxColor, &minColor);

            insetBBox(&maxColor, &minColor);

            ushort color0 = roundAndExpand(&maxColor);
            ushort color1 = roundAndExpand(&minColor);

            if (color0 < color1)
            {
                Vector3 t = maxColor;
                maxColor = minColor;
                minColor = t;
                VoidPtr.Swap(&color0, &color1);
            }

            CMPRBlock block = new CMPRBlock();

            block._root0._data = color0;
            block._root1._data = color1;
            block._lookup      = computeIndices4(points, &maxColor, &minColor);


            optimizeEndPoints4(points, &block);

            return(block);
        }
示例#5
0
        public static CMPRBlock compressDXT1a(ARGBPixel *img, int imgX, int imgY, int imgW, int imgH)
        {
            uint *     pData  = stackalloc uint[16];
            ARGBPixel *pBlock = (ARGBPixel *)pData;

            bool hasAlpha = false;
            bool isSingle = true;

            ARGBPixel  p;
            ARGBPixel *sPtr  = img + (imgX + imgY * imgW);
            int        index = 0;

            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    p = sPtr[x + y * imgW];
                    pBlock[index++] = p;
                    if (p != pBlock[0])
                    {
                        isSingle = false;
                    }

                    if (p.A < 128)
                    {
                        hasAlpha = true;
                    }
                }
            }

            if (isSingle)
            {
                return(optimalCompressDXT1a(sPtr[0]));
            }

            if (!hasAlpha)
            {
                return(compressDXT1(pBlock));
            }

            // @@ Handle single RGB, with varying alpha? We need tables for single color compressor in 3 color mode.
            //else if (rgba.isSingleColorNoAlpha()) { ... }

            float *  pointData = stackalloc float[48];
            Vector3 *points    = (Vector3 *)pointData;

            // read block
            //Vector3 block[16];
            int num = extractColorBlockRGBA(pBlock, points);

            // find min and max colors
            Vector3 maxColor, minColor;

            findMinMaxColorsBox(points, num, &maxColor, &minColor);

            selectDiagonal(points, num, &maxColor, &minColor);

            insetBBox(&maxColor, &minColor);

            ushort color0 = roundAndExpand(&maxColor);
            ushort color1 = roundAndExpand(&minColor);

            if (color0 < color1)
            {
                Vector3 t = maxColor;
                maxColor = minColor;
                minColor = t;
                VoidPtr.Swap(&color0, &color1);
            }

            CMPRBlock block = new CMPRBlock();

            block._root0._data = color1;
            block._root1._data = color0;
            block._lookup      = computeIndices3(pBlock, &maxColor, &minColor);

            //	optimizeEndPoints(block, dxtBlock);

            return(block);
        }