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); }
protected override void EncodeBlock(ARGBPixel *sPtr, VoidPtr blockAddr, int width) { CMPRBlock *dPtr = (CMPRBlock *)blockAddr; for (int y = 0; y < 2; y++, sPtr += (width * 4)) { for (int x = 0; x < 8; x += 4) { *dPtr++ = CMPRBlock.Encode(&sPtr[x], width, false); } } }
public UnsafeBuffer GeneratePreview(Bitmap bmp) { //_blockCache.Clear(); int w = bmp.Width, h = bmp.Height; int aw = w.Align(BlockWidth), ah = h.Align(BlockHeight); UnsafeBuffer buffer = new UnsafeBuffer((aw / 4) * (ah / 4) * 8); CMPRBlock * bPtr = (CMPRBlock *)buffer.Address; //using (Bitmap bmp = src.Clone(new Rectangle(0, 0, aw, ah), PixelFormat.Format32bppArgb)) //{ // BitmapData data = bmp.LockBits(new Rectangle(0,0,aw,ah), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); // for (int y1 = 0; y1 < ah; y1 += 8) // for (int x1 = 0; x1 < aw; x1 += 8) // for (int y = 0; y < 8; y += 4) // for (int x = 0; x < 8; x += 4) // { // ARGBPixel* ptr = (ARGBPixel*)dib.Scan0 + (((y1 + y) * aw) + (x1 + x)); // CMPBlock block = CMPBlock.Encode(ptr, aw, false); // _blockCache.Add(block); // block.Decode(ptr, aw); // } //} using (DIB dib = DIB.FromBitmap(bmp, BlockWidth, BlockHeight, PixelFormat.Format32bppArgb)) { ARGBPixel *img = (ARGBPixel *)dib.Scan0; for (int y1 = 0; y1 < ah; y1 += 8) { for (int x1 = 0; x1 < aw; x1 += 8) { for (int y = 0; y < 8; y += 4) { for (int x = 0; x < 8; x += 4) { *bPtr = NVDXT.compressDXT1a(img, x1 + x, y1 + y, aw, ah); bPtr->Decode(img, x1 + x, y1 + y, aw, ah); bPtr++; } } } } dib.WriteBitmap(bmp, w, h); } return(buffer); }
//private List<CMPBlock> _blockCache = new List<CMPBlock>(); //private int _blockIndex; protected override void DecodeBlock(VoidPtr blockAddr, ARGBPixel *dPtr, int width) { CMPRBlock *sPtr = (CMPRBlock *)blockAddr; //ARGBPixel* dPtr = (ARGBPixel*)destAddr; //int index = 0; for (int y = 0; y < 8; y += 4) { for (int x = 0; x < 8; x += 4, sPtr++) { sPtr->Decode(&dPtr[(y * width) + x], width); } } //DXT1.DecodeBlock(&sPtr[index++], &dPtr[(y * width) + x], width); }
//internal override void EncodeLevel(TEX0v1* header, DIB dib, Bitmap src, int dStep, int sStep, int level) //{ // if ((level == 1) && (_blockBuffer != null)) // { // CMPRBlock* sPtr = (CMPRBlock*)_blockBuffer.Address; // CMPRBlock* dPtr = (CMPRBlock*)header->PixelData; // int blocks = _blockBuffer.Length / 8; // for (int i = 0; i < blocks; i++) // dPtr[i] = sPtr[i]; // } // else // base.EncodeLevel(header, dib, src, dStep, sStep, level); //} internal override void EncodeLevel(VoidPtr addr, DIB dib, Bitmap src, int dStep, int sStep, int level) { if ((level == 1) && (_blockBuffer != null)) { CMPRBlock *sPtr = (CMPRBlock *)_blockBuffer.Address; CMPRBlock *dPtr = (CMPRBlock *)addr; int blocks = _blockBuffer.Length / 8; for (int i = 0; i < blocks; i++) { dPtr[i] = sPtr[i]; } } else { base.EncodeLevel(addr, dib, src, dStep, sStep, level); } }