예제 #1
0
        private static unsafe void compressMasked(byte *rgba, int mask, byte *block, SquishFlags flags)
        {
            //
            // get the block locations
            //
            byte *colourBlock = block;
            byte *alphaBlock  = block;

            if ((flags & (SquishFlags.Dxt3 | SquishFlags.Dxt5)) != 0)
            {
                colourBlock = block + 8;
            }
            //
            // create the minimal point set
            //
            ColourSet colours = new ColourSet(rgba, mask, flags);

            //
            // check the compression type and compress colour
            //
            if (colours.Count == 1)
            {
                //
                // always do a single colour fit
                //
                SingleColourFit fit = new SingleColourFit(colours, flags);

                fit.Compress(colourBlock);
            }
            else if ((flags & SquishFlags.ColourRangeFit) != 0 || colours.Count == 0)
            {
                //
                // do a range fit
                //
                RangeFit fit = new RangeFit(colours, flags);

                fit.Compress(colourBlock);
            }
            else
            {
                //
                // default to a cluster fit (could be iterative or not)
                //
                ClusterFit fit = new ClusterFit(colours, flags);

                fit.Compress(colourBlock);
            }
            //
            // compress alpha separately if necessary
            //
            if ((flags & SquishFlags.Dxt3) != 0)
            {
                compressAlphaDxt3(rgba, mask, alphaBlock);
            }
            else if ((flags & SquishFlags.Dxt5) != 0)
            {
                compressAlphaDxt5(rgba, mask, alphaBlock);
            }
        }
예제 #2
0
    public SingleColourFit(ColourSet colours, SquishFlags flags) : base(colours, flags) {
      //
      // grab the single colour
      //
      Vec3[] values = colours.Points;

      colour[0] = (byte)ColourBlock.FloatToInt(255.0f * values[0].X, 255);
      colour[1] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Y, 255);
      colour[2] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Z, 255);
      //
      // initialise the best error
      //
      bestError = Int32.MaxValue;
    }
예제 #3
0
        public SingleColourFit(ColourSet colours, SquishFlags flags) : base(colours, flags)
        {
            //
            // grab the single colour
            //
            Vec3[] values = colours.Points;

            colour[0] = (byte)ColourBlock.FloatToInt(255.0f * values[0].X, 255);
            colour[1] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Y, 255);
            colour[2] = (byte)ColourBlock.FloatToInt(255.0f * values[0].Z, 255);
            //
            // initialise the best error
            //
            bestError = Int32.MaxValue;
        }
예제 #4
0
    private static unsafe void compressMasked(byte *rgba, int mask, byte *block, SquishFlags flags) {
      //
      // get the block locations
      //
      byte *colourBlock = block;
      byte *alphaBlock  = block;

      if ((flags & (SquishFlags.Dxt3 | SquishFlags.Dxt5)) != 0) colourBlock = block + 8;
      //
      // create the minimal point set
      //
      ColourSet colours = new ColourSet(rgba, mask, flags);
      //
      // check the compression type and compress colour
      //
      if (colours.Count == 1) {
        //
        // always do a single colour fit
        //
        SingleColourFit fit = new SingleColourFit(colours, flags);

        fit.Compress(colourBlock);
      }
      else if ((flags & SquishFlags.ColourRangeFit) != 0 || colours.Count == 0) {
        //
        // do a range fit
        //
        RangeFit fit = new RangeFit(colours, flags);

        fit.Compress(colourBlock);
      }
      else {
        //
        // default to a cluster fit (could be iterative or not)
        //
        ClusterFit fit = new ClusterFit(colours, flags);

        fit.Compress(colourBlock);
      }
      //
      // compress alpha separately if necessary
      //
      if ((flags & SquishFlags.Dxt3) != 0) compressAlphaDxt3(rgba, mask, alphaBlock);
      else if ((flags & SquishFlags.Dxt5) != 0) compressAlphaDxt5(rgba, mask, alphaBlock);
    }
예제 #5
0
    public ClusterFit(ColourSet Colours, SquishFlags Flags) : base(Colours, Flags) {
      //
      // initialise the metric
      //
      bool isPerceptual = (flags & SquishFlags.ColourMetricPerceptual) != 0;

      metric = isPerceptual ? new Vec3(0.2126f, 0.7152f, 0.0722f) : new Vec3(1.0f);
      //
      // initialise the best error
      //
      bestError = Single.MaxValue;
      //
      // cache some values
      //
      int count = colours.Count;

      Vec3[] values = colours.Points;

      float[] weights = colours.Weights;
      //
      // get the covariance matrix
      //
      Sym3x3 covariance = Maths.ComputeWeightedCovariance(count, values, weights);
      //
      // compute the principle component
      //
      Vec3 principle = Maths.ComputePrincipleComponent(covariance);
      //
      // get the min and max range as the codebook endpoints
      //
      Vec3 startTemp = new Vec3(0.0f);
      Vec3   endTemp = new Vec3(0.0f);

      if (count > 0) {
        //
        // compute the range
        //
        startTemp = endTemp = values[0];

        float min = Vec3.Dot(values[0], principle);

        float max = min;

        for(int i = 1; i < count; ++i) {
          float val = Vec3.Dot(values[i], principle);

          if (val < min) {
            startTemp = values[i];

            min = val;
          }
          else {
            if (val > max) {
              endTemp = values[i];

              max = val;
            }
          }
        }
      }
      //
      // clamp the output to [0, 1]
      //
      Vec3 one  = new Vec3(1.0f);
      Vec3 zero = new Vec3(0.0f);

      startTemp = Vec3.Min(one, Vec3.Max(zero, startTemp));
      endTemp   = Vec3.Min(one, Vec3.Max(zero, endTemp));
      //
      // clamp to the grid and save
      //
      Vec3 grid    = new Vec3(31.0f, 63.0f, 31.0f);
      Vec3 gridrcp = new Vec3(1.0f / 31.0f, 1.0f / 63.0f, 1.0f / 31.0f);
      Vec3 half    = new Vec3(0.5f);

      start = Vec3.Truncate(grid * startTemp + half) * gridrcp;
      end   = Vec3.Truncate(grid * endTemp   + half) * gridrcp;
    }
예제 #6
0
 protected ColourFit(ColourSet Colours, SquishFlags Flags)
 {
     colours = Colours;
     flags   = Flags;
 }
예제 #7
0
        public ClusterFit(ColourSet Colours, SquishFlags Flags) : base(Colours, Flags)
        {
            //
            // initialise the metric
            //
            bool isPerceptual = (flags & SquishFlags.ColourMetricPerceptual) != 0;

            metric = isPerceptual ? new Vec3(0.2126f, 0.7152f, 0.0722f) : new Vec3(1.0f);
            //
            // initialise the best error
            //
            bestError = Single.MaxValue;
            //
            // cache some values
            //
            int count = colours.Count;

            Vec3[] values = colours.Points;

            float[] weights = colours.Weights;
            //
            // get the covariance matrix
            //
            Sym3x3 covariance = Maths.ComputeWeightedCovariance(count, values, weights);
            //
            // compute the principle component
            //
            Vec3 principle = Maths.ComputePrincipleComponent(covariance);
            //
            // get the min and max range as the codebook endpoints
            //
            Vec3 startTemp = new Vec3(0.0f);
            Vec3 endTemp   = new Vec3(0.0f);

            if (count > 0)
            {
                //
                // compute the range
                //
                startTemp = endTemp = values[0];

                float min = Vec3.Dot(values[0], principle);

                float max = min;

                for (int i = 1; i < count; ++i)
                {
                    float val = Vec3.Dot(values[i], principle);

                    if (val < min)
                    {
                        startTemp = values[i];

                        min = val;
                    }
                    else
                    {
                        if (val > max)
                        {
                            endTemp = values[i];

                            max = val;
                        }
                    }
                }
            }
            //
            // clamp the output to [0, 1]
            //
            Vec3 one  = new Vec3(1.0f);
            Vec3 zero = new Vec3(0.0f);

            startTemp = Vec3.Min(one, Vec3.Max(zero, startTemp));
            endTemp   = Vec3.Min(one, Vec3.Max(zero, endTemp));
            //
            // clamp to the grid and save
            //
            Vec3 grid    = new Vec3(31.0f, 63.0f, 31.0f);
            Vec3 gridrcp = new Vec3(1.0f / 31.0f, 1.0f / 63.0f, 1.0f / 31.0f);
            Vec3 half    = new Vec3(0.5f);

            start = Vec3.Truncate(grid * startTemp + half) * gridrcp;
            end   = Vec3.Truncate(grid * endTemp + half) * gridrcp;
        }
예제 #8
0
 protected ColourFit(ColourSet Colours, SquishFlags Flags) {
   colours = Colours;
   flags   = Flags;
 }