private static List <ImageSlice> ParseSlices(byte[] imageData) { // tiles are 16 x 8 but 4bpp, so each byte is 2 pixels, so 8x8 in bytes // stride is always 512 bytes List <ImageSlice> slices = new List <ImageSlice>(); int numBytes = imageData.Length; const int stride = 256; // in bytes, not pixels const int xTiles = stride / 8; int yTiles = numBytes / stride / 8; for (int yTile = 0; yTile < yTiles; ++yTile) { int yPos = yTile * 8; for (int xTile = 0; xTile < xTiles; xTile++) { int xPos = xTile * 8; // also used as byte index ImageSlice s = new ImageSlice(); for (int localIter = 0; localIter < (16 * 8); localIter += 2) { int localX = localIter % 16; int localY = localIter / 16; Debug.Assert((localY >= 0) && (localY < 8)); int yPixOffset = (yPos + localY) * stride; byte twoPix = imageData[yPixOffset + xPos + (localX / 2)]; s.rect[((localY * 16) + localX) + 1] = (byte)((twoPix & 0xF0) >> 4); s.rect[((localY * 16) + localX)] = (byte)(twoPix & 0xF); } slices.Add(s); } } return(slices); }
private static List <ImageSlice> ParseSlices(byte[] imageData) { // tiles are 8 x 8 in ed53 // stride is always 512 bytes List <ImageSlice> slices = new List <ImageSlice>(); int numBytes = imageData.Length; const int stride = 512; const int xTiles = stride / 8; int yTiles = numBytes / stride / 8; for (int yTile = 0; yTile < yTiles; ++yTile) { int yPos = yTile * 8; for (int xTile = 0; xTile < xTiles; xTile++) { int xPos = (xTile * 8); ImageSlice s = new ImageSlice(xPos, yPos); for (int localIter = 0; localIter < (8 * 8); ++localIter) { int localX = localIter % 8; int localY = localIter / 8; Debug.Assert((localY >= 0) && (localY < 8)); int yPixOffset = (yPos + localY) * stride; s.rect[(localY * 8) + localX] = imageData[yPixOffset + xPos + localX]; } slices.Add(s); } } //slices.Sort(); return(slices); }
public Renderer.Texture2D CreateTextureCube(Renderer.Device _Device) { if (m_Opts.m_type != ImageOptions.TYPE.TT_CUBIC) { throw new Exception("The image is not a cube map texture!"); } ImageUtility.PIXEL_FORMAT textureFormat = ImageUtility.PIXEL_FORMAT.UNKNOWN; ImageUtility.COMPONENT_FORMAT componentFormat; m_Opts.m_format.GetEquivalentRendererFormat(out textureFormat, out componentFormat); uint ArraySize = 6 * m_Opts.m_arraySize; uint MipsCount = m_Opts.m_curNumLevels; uint PixelSize = m_Opts.m_format.BitsCount >> 3; List <Renderer.PixelsBuffer> Content = new List <Renderer.PixelsBuffer>(); for (uint SliceIndex = 0; SliceIndex < ArraySize; SliceIndex++) { for (uint MipLevelIndex = 0; MipLevelIndex < MipsCount; MipLevelIndex++) { ImageSlice Slice = m_Slices[MipLevelIndex * ArraySize + SliceIndex]; // Stupidly stored in reverse order! Renderer.PixelsBuffer Pixels = new Renderer.PixelsBuffer((uint)(Slice.m_Width * Slice.m_Height * PixelSize)); Content.Add(Pixels); using (BinaryWriter Writer = Pixels.OpenStreamWrite()) Writer.Write(Slice.m_Content); } } Renderer.Texture2D Result = new Renderer.Texture2D(_Device, m_Opts.m_curWidth, m_Opts.m_curHeight, -6 * (int)m_Opts.m_arraySize, m_Opts.m_curNumLevels, textureFormat, componentFormat, false, false, Content.ToArray()); return(Result); }
/// <summary> /// Creates a 2D texture from the image /// </summary> /// <returns></returns> public RendererManaged.Texture2D CreateTexture2D(RendererManaged.Device _Device) { if (m_Opts.m_type != ImageOptions.TYPE.TT_2D) { throw new Exception("The image is not a 2D texture!"); } RendererManaged.PIXEL_FORMAT TextureFormat = m_Opts.m_format.EquivalentRendererFormat; uint ArraySize = m_Opts.m_arraySize; uint MipsCount = m_Opts.m_curNumLevels; uint PixelSize = m_Opts.m_format.BitsCount >> 3; List <RendererManaged.PixelsBuffer> Content = new List <RendererManaged.PixelsBuffer>(); for (uint SliceIndex = 0; SliceIndex < ArraySize; SliceIndex++) { for (uint MipLevelIndex = 0; MipLevelIndex < MipsCount; MipLevelIndex++) { ImageSlice Slice = m_Slices[MipLevelIndex * ArraySize + SliceIndex]; // Stupidly stored in reverse order! RendererManaged.PixelsBuffer Pixels = new RendererManaged.PixelsBuffer((int)(Slice.m_Width * Slice.m_Height * PixelSize)); Content.Add(Pixels); using (BinaryWriter Writer = Pixels.OpenStreamWrite()) Writer.Write(Slice.m_Content); } } RendererManaged.Texture2D Result = new RendererManaged.Texture2D(_Device, (int)m_Opts.m_curWidth, (int)m_Opts.m_curHeight, (int)m_Opts.m_arraySize, (int)m_Opts.m_curNumLevels, TextureFormat, false, false, Content.ToArray()); return(Result); }
private static void ArrangeSlices(Bitmap bm, List <ImageSlice> slices, List <Palette> palettes, List <GTMPFile.PositionData> posData) { Rectangle lockRect = new Rectangle(0, 0, bm.Width, bm.Height); BitmapData bd = bm.LockBits(lockRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); // docs say this is pixel width, it's a dirty liar. It's the byte width int byteStride = bd.Stride; foreach (GTMPFile.PositionData pd in posData) { int[] colourData = new int[16 * 8]; bool makeTopLeftBlack = false; ushort actualTile = pd.tile; //if ((pd.tile & 0x0800) != 0) //{ // actualTile = (ushort)(pd.tile & ~0x800); // makeTopLeftBlack = true; //} if (pd.palette != 0xFF) { ImageSlice tile = slices[actualTile]; Palette p = palettes[pd.palette]; Color topLeft = p.colours[tile.rect[0]]; for (int i = 0; i < (16 * 8); ++i) { byte colourIndex = tile.rect[i]; Color pixelColour = p.colours[colourIndex]; if (makeTopLeftBlack && (pixelColour == topLeft)) { colourData[i] = Color.Black.ToArgb(); //(int)(pixelColour.ToArgb() & 0x00FFFFFF); } else { colourData[i] = pixelColour.ToArgb(); } } } else { Color blockColour = GTMPFile.MakeColorFromBGR555(actualTile); int colourRGB = blockColour.ToArgb(); for (int i = 0; i < (16 * 8); ++i) { colourData[i] = colourRGB; } } IntPtr scanLineIter = new IntPtr(bd.Scan0.ToInt64() + ((pd.y * byteStride) + (pd.x * 4))); for (int i = 0; i < 8; ++i) { Marshal.Copy(colourData, i * 16, scanLineIter, 16); scanLineIter = new IntPtr(scanLineIter.ToInt64() + bd.Stride); } } bm.UnlockBits(bd); }
private void Start() { Init(ImageSlice.GetPiece(img, Vector2Int.zero, new Vector2Int(5, 5)), new Vector2(0, 0)); Init(ImageSlice.GetPiece(img, new Vector2Int(0, 1), new Vector2Int(5, 5)), new Vector2(0, 1)); Mesh meshCombine = CombineMeshes(new List <Mesh> { transform.GetChild(0).GetComponent <Mesh>(), transform.GetChild(1).GetComponent <Mesh>() }); GameObject tempQuad = GameObject.CreatePrimitive(PrimitiveType.Quad); tempQuad.GetComponent <MeshFilter>().mesh = meshCombine; }
void CreatePuzzle() { Texture2D[,] _imageSlice = ImageSlice.GetSlice(image, blockPerLine); for (int x = 0; x < blockPerLine; x++) { for (int y = 0; y < blockPerLine; y++) { GameObject _blockObject = GameObject.CreatePrimitive(PrimitiveType.Quad); //GameObject _blockObject = GameObject.Instantiate(block , transform.position, Quaternion.identity); _blockObject.transform.position = -Vector2.one * (blockPerLine - 1) * 0.5f + new Vector2(x, y); _blockObject.transform.parent = transform; _blockObject.AddComponent <Piece>(); Block _block = _blockObject.AddComponent <Block>(); _block.coord = new Vector2Int(x, y); _block.Init(new Vector2Int(x, y), _imageSlice[x, y]); } } }
private static void ArrangeSlicesIndexed(Bitmap bm, List <ImageSlice> slices, List <Palette> palettes, List <PositionData> posData) { Rectangle lockRect = new Rectangle(0, 0, bm.Width, bm.Height); BitmapData bd = bm.LockBits(lockRect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // docs say this is pixel width, it's a dirty liar. It's the byte width int byteStride = bd.Stride; foreach (PositionData pd in posData) { byte[] colourData = new byte[16 * 8]; if (pd.palette != 0xFF) { ImageSlice tile = slices[pd.tile]; Palette p = palettes[pd.palette]; for (int i = 0; i < (16 * 8); ++i) { colourData[i] = (byte)((pd.palette * 16) + tile.rect[i]); } } else { Color blockColour = MakeColorFromBGR555(pd.tile); byte index = FindNearestColourIndex(blockColour, palettes); for (int i = 0; i < (16 * 8); ++i) { colourData[i] = index; } } // find the starting position for this position data IntPtr scanLineIter = new IntPtr(bd.Scan0.ToInt64() + ((pd.y * byteStride) + (pd.x))); for (int i = 0; i < 8; ++i) { // copy the pixels for this row Marshal.Copy(colourData, i * 16, scanLineIter, 16); // go to next row scanLineIter = new IntPtr(scanLineIter.ToInt64() + bd.Stride); } } bm.UnlockBits(bd); }
private static void ArrangeSlices(Bitmap bm, List <ImageSlice> slices, List <Palette> palettes, List <PositionData> posData) { Rectangle lockRect = new Rectangle(0, 0, bm.Width, bm.Height); BitmapData bd = bm.LockBits(lockRect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); int byteStride = bd.Stride; ImageSlice previous = null; foreach (PositionData pd in posData) { int[] colourData = new int[8 * 8]; // hack - what to do if pd.tile > slices.count if (pd.tile < slices.Count) { ImageSlice tile = slices[pd.tile]; // also hack if (tile != previous) { Palette p = palettes[pd.palette]; for (int i = 0; i < (8 * 8); ++i) { colourData[i] = p.colours[tile.rect[i]].ToArgb(); } } previous = tile; } // end of hack IntPtr scanLineIter = new IntPtr(bd.Scan0.ToInt64() + ((pd.y * byteStride) + (pd.x * 4))); for (int i = 0; i < 8; ++i) { Marshal.Copy(colourData, i * 8, scanLineIter, 8); scanLineIter = new IntPtr(scanLineIter.ToInt64() + bd.Stride); } } bm.UnlockBits(bd); }