/// <summary> /// Updates the specified atlas with a given TexImage. /// </summary> /// <param name="atlas">The atlas.</param> /// <param name="request">The request.</param> /// <exception cref="TexLibraryException">The request texture name + request.Name + doesn't exist in this atlas.</exception> private void Update(TexAtlas atlas, AtlasUpdateRequest request) { if (!atlas.Layout.TexList.ContainsKey(request.Name)) { Log.Error("The given texture name " + request.Name + " doesn't exist in this atlas."); throw new TextureToolsException("The given texture name " + request.Name + " doesn't exist in this atlas."); } TexAtlas.TexLayout.Position position = atlas.Layout.TexList[request.Name]; if (request.Texture.Width != position.Width || request.Texture.Height != position.Height) { Log.Error("The given texture must match the dimension of the one you want to update in the atlas."); throw new TextureToolsException("The given texture must match the dimension of the one you want to update in the atlas."); } int mipmapCount = 0; int w = position.Width; int h = position.Height; do { ++mipmapCount; w >>= 1; h >>= 1; }while (w >= 1 && h >= 1 && mipmapCount < atlas.MipmapCount); w = position.Width; h = position.Height; int x = position.UOffset; int y = position.VOffset; long subImageData, atlasData; int xOffset, yOffset; for (int i = 0; i < mipmapCount; ++i) { xOffset = (int)((Decimal)x / atlas.SubImageArray[i].Width * atlas.SubImageArray[i].RowPitch); yOffset = y * atlas.SubImageArray[i].RowPitch; subImageData = request.Texture.SubImageArray[i].Data.ToInt64(); atlasData = atlas.SubImageArray[i].Data.ToInt64(); for (int j = 0; j < h; ++j) { Utilities.CopyMemory(new IntPtr(atlasData + j * atlas.SubImageArray[i].RowPitch + yOffset + xOffset), new IntPtr(subImageData + j * request.Texture.SubImageArray[i].RowPitch), request.Texture.SubImageArray[i].RowPitch); } w = w > 1 ? w >>= 1 : w; h = h > 1 ? h >>= 1 : h; x = x <= 1 ? 0 : x >>= 1; y = y <= 1 ? 0 : y >>= 1; } }
/// <summary> /// Extracts the specified texture from the atlas. /// </summary> /// <param name="atlas">The atlas.</param> /// <param name="texture">The texture that will be filled.</param> /// <param name="position">The position of the texture in the atlas.</param> private void ExtractTexture(TexAtlas atlas, TexImage texture, TexAtlas.TexLayout.Position position, int minimumMipmapSize) { texture.Format = atlas.Format; int x, y, w, h, rowPitch, slicePitch, mipmapCount, dataSize, offset; dataSize = 0; mipmapCount = 0; w = position.Width; h = position.Height; do { Tools.ComputePitch(texture.Format, w, h, out rowPitch, out slicePitch); dataSize += slicePitch; ++mipmapCount; w >>= 1; h >>= 1; }while (w >= minimumMipmapSize && h >= minimumMipmapSize && mipmapCount < atlas.MipmapCount); texture.MipmapCount = mipmapCount; texture.SubImageArray = new TexImage.SubImage[mipmapCount]; texture.Data = Marshal.AllocHGlobal(dataSize); texture.DataSize = dataSize; texture.Width = position.Width; texture.Height = position.Height; long atlasData, textureData; int xOffset, yOffset; IntPtr destPtr, srcPtr; w = position.Width; h = position.Height; x = position.UOffset; y = position.VOffset; offset = 0; for (int i = 0; i < mipmapCount; ++i) { Tools.ComputePitch(texture.Format, w, h, out rowPitch, out slicePitch); texture.SubImageArray[i] = new TexImage.SubImage(); texture.SubImageArray[i].Data = new IntPtr(texture.Data.ToInt64() + offset); texture.SubImageArray[i].DataSize = slicePitch; texture.SubImageArray[i].Width = w; texture.SubImageArray[i].Height = h; texture.SubImageArray[i].RowPitch = rowPitch; texture.SubImageArray[i].SlicePitch = slicePitch; atlasData = atlas.SubImageArray[i].Data.ToInt64(); textureData = texture.SubImageArray[i].Data.ToInt64(); xOffset = (int)((Decimal)x / atlas.SubImageArray[i].Width * atlas.SubImageArray[i].RowPitch); yOffset = y * atlas.SubImageArray[i].RowPitch; for (int j = 0; j < h; ++j) { srcPtr = new IntPtr(atlasData + j * atlas.SubImageArray[i].RowPitch + yOffset + xOffset); destPtr = new IntPtr(textureData + j * rowPitch); Utilities.CopyMemory(destPtr, srcPtr, rowPitch); } offset += slicePitch; w = w > 1 ? w >>= 1 : w; h = h > 1 ? h >>= 1 : h; x = x <= 1 ? 0 : x >>= 1; y = y <= 1 ? 0 : y >>= 1; } texture.RowPitch = texture.SubImageArray[0].RowPitch; texture.SlicePitch = texture.SubImageArray[0].SlicePitch; texture.DisposingLibrary = this; }