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; }
protected override unsafe void Compress4(byte *block) { // // build the table of lookups // SingleColourLookup[][] lookups = { SingleColourLookups.Lookup_5_4, SingleColourLookups.Lookup_6_4, SingleColourLookups.Lookup_5_4 }; // // find the best end-points and index // computeEndPoints(lookups); // // build the block if we win // if (error < bestError) { // // remap the indices // byte[] indices = new byte[16]; // // The c++ passed a pointer to index and that pointer was used as an array. If the RemapIndices method // throws an IndexOutOfRangeException, then it was definitely a bug in the c++. // colours.RemapIndices(new byte[] { index }, indices); // // save the block // ColourBlock.WriteColourBlock4(start, end, indices, block); // // save the error // bestError = error; } }
private static unsafe void compressAlphaDxt3(byte *rgba, int mask, byte *block) { byte *bytes = block; // // quantise and pack the alpha values pairwise // for (int i = 0; i < 8; ++i) { // // quantise down to 4 bits // float alpha1 = rgba[8 * i + 3] * (15.0f / 255.0f); float alpha2 = rgba[8 * i + 7] * (15.0f / 255.0f); int quant1 = ColourBlock.FloatToInt(alpha1, 15); int quant2 = ColourBlock.FloatToInt(alpha2, 15); // // set alpha to zero where masked // int bit1 = 1 << (2 * i); int bit2 = 1 << (2 * i + 1); if ((mask & bit1) == 0) { quant1 = 0; } if ((mask & bit2) == 0) { quant2 = 0; } // // pack into the byte // bytes[i] = (byte)(quant1 | (quant2 << 4)); } }
protected override unsafe void Compress4(byte *block) { // // cache some values // int count = colours.Count; Vec3[] values = colours.Points; // // create a codebook // Vec3[] codes = new Vec3[4]; codes[0] = start; codes[1] = end; codes[2] = 2.0f / 3.0f * start + 1.0f / 3.0f * end; codes[3] = 1.0f / 3.0f * start + 2.0f / 3.0f * end; // // match each point to the closest code // byte[] closest = new byte[16]; float error = 0.0f; for (int i = 0; i < count; ++i) { // // find the closest code // float dist = Single.MaxValue; int idx = 0; for (int j = 0; j < 4; ++j) { float d = Vec3.LengthSquared(metric * (values[i] - codes[j])); if (d < dist) { dist = d; idx = j; } } // // save the index // closest[i] = (byte)idx; // // accumulate the error // error += dist; } // // save this scheme if it wins // if (error < bestError) { // // remap the indices // byte[] indices = new byte[16]; colours.RemapIndices(closest, indices); // // save the block // ColourBlock.WriteColourBlock4(start, end, indices, block); // // save the error // bestError = error; } }