private static int ClonePixel(BitmapData dataOrig, BitmapData dataNew, VRageMath.Vector2I tileBorder, byte[] dataBytesOrig, int iRowOrig, int iColumnOrig, byte[] dataBytesNew, int iRowNew, int iColumnNew) { for (int iMargin = 0; iMargin < tileBorder.X; iMargin++) { Buffer.BlockCopy(dataBytesOrig, iRowOrig * dataOrig.Stride + 4 * iColumnOrig, dataBytesNew, iRowNew * dataNew.Stride + 4 * iColumnNew, 4); iColumnNew++; } return(iColumnNew); }
// simulates OpenGL's GL_CLAMP_TO_EDGE on the tileset protected static void IncreaseTileBorders(BitmapData dataOrig, BitmapData dataNew, int tilesPerRow, int tilesPerColumn, TilesetImage tilesetImage) { VRageMath.Vector2I tileSize = tilesetImage.TileSize; VRageMath.Vector2I tileBorder = tilesetImage.TileBorder; VRageMath.Vector2I tileMargin = tilesetImage.TileMargin; // Get the address of the first line. IntPtr dataOrigPtr = dataOrig.Scan0; IntPtr dataNewPtr = dataNew.Scan0; // Declare an array to hold the bytes of the bitmap. int bytesOrig = Math.Abs(dataOrig.Stride) * dataOrig.Height; int bytesNew = Math.Abs(dataNew.Stride) * dataNew.Height; byte[] dataBytesOrig = new byte[bytesOrig]; byte[] dataBytesNew = new byte[bytesNew]; // Copy the RGB values into the array. System.Runtime.InteropServices.Marshal.Copy(dataOrigPtr, dataBytesOrig, 0, bytesOrig); int iRowOrig = 0; int iRowNew = 0; for (int i = 0; i < tilesPerColumn; i++) { // space between tiles if (i != 0) { iRowOrig += tileMargin.Y; iRowNew += tileMargin.Y; } // tiles for (int iTileY = 0; iTileY < tileSize.Y; iTileY++) { int iColumnOrig = 0; int iColumnNew = 0; // the copy operations multiply bytes by 4, because the pixel is 32 bits // copy the tile row for (int j = 0; j < tilesPerRow; j++) { if (j != 0) { iColumnOrig += tileMargin.X; iColumnNew += tileMargin.X; } // copy the leading pixel (tileBorder.X times) iColumnNew = ClonePixel(dataOrig, dataNew, tileBorder, dataBytesOrig, iRowOrig, iColumnOrig, dataBytesNew, iRowNew, iColumnNew); // copy the tile pixels Buffer.BlockCopy(dataBytesOrig, iRowOrig * dataOrig.Stride + 4 * iColumnOrig, dataBytesNew, iRowNew * dataNew.Stride + 4 * iColumnNew, 4 * tileSize.X); iColumnOrig += tileSize.X; iColumnNew += tileSize.X; // copy the trailing pixel (tileBorder.X times) iColumnNew = ClonePixel(dataOrig, dataNew, tileBorder, dataBytesOrig, iRowOrig, iColumnOrig - 1, dataBytesNew, iRowNew, iColumnNew); } PremultiplyAlpha(dataBytesNew, dataNew.Stride, iRowNew); // if first or last tile row was copied, duplicate it (tileBorder.Y times) if (iTileY == 0 || iTileY == tileSize.Y - 1) { for (int iMargin = 0; iMargin < tileBorder.Y; iMargin++) { // copy the current row in dataNew to next row Buffer.BlockCopy(dataBytesNew, iRowNew * dataNew.Stride, dataBytesNew, (iRowNew + 1) * dataNew.Stride, dataNew.Stride); iRowNew++; } } iRowNew++; iRowOrig++; } } System.Runtime.InteropServices.Marshal.Copy(dataBytesNew, 0, dataNewPtr, bytesNew); }