public static int GetMipmapCount(int width, int height, UnityCompatibleFormat format, int dataLengthPerImage) { int divSize = format == UnityCompatibleFormat.DXT1 || format == UnityCompatibleFormat.DXT5 ? 4 : 1; int blockBytes = format == UnityCompatibleFormat.DXT1 ? 8 : format == UnityCompatibleFormat.DXT5 ? 16 : format == UnityCompatibleFormat.RGBA32 || format == UnityCompatibleFormat.ARGB32 ? 4 : 3; int mipmaps = 0; int len = 0; for (int size; len < dataLengthPerImage; len += size) { int blockWidth = Math.Max(divSize, (width + divSize - 1)) / divSize; int blockHeight = Math.Max(divSize, (height + divSize - 1)) / divSize; int blocks = blockWidth * blockHeight; size = blocks * blockBytes; if (width > 1) { width >>= 1; } if (height > 1) { height >>= 1; } mipmaps++; } if (len != dataLengthPerImage) { mipmaps--; Report.ReportLog("Warning! Texture is incomplete - mipmaps capped to " + mipmaps); } return(mipmaps); }
public static byte[] CreateHeader(int width, int height, int rgbBitCount, int mipMaps, bool cubemap, UnityCompatibleFormat format) { uint fourCC = format == UnityCompatibleFormat.DXT1 ? FOURCC_DXT1 : format == UnityCompatibleFormat.DXT5 ? FOURCC_DXT5 : /*format == UnityCompatibleFormat.RGBAFloat || format == UnityCompatibleFormat.RGBAHalf ||*/ format == UnityCompatibleFormat.BC7 ? FOURCC_DX10 : format == UnityCompatibleFormat.RGBAFloat ? (uint)SlimDX.Direct3D9.Format.A32B32G32R32F : format == UnityCompatibleFormat.RGBAHalf ? (uint)SlimDX.Direct3D9.Format.A16B16G16R16F : 0; uint[] header = new uint[32 + (/*format == UnityCompatibleFormat.RGBAFloat || format == UnityCompatibleFormat.RGBAHalf ||*/ format == UnityCompatibleFormat.BC7 ? 5 : 0)]; header[0] = (byte)'D' | ((byte)'D' << 8) | ((byte)'S' << 16) | ((byte)' ' << 24); header[1] = 124; // sizeof DDS_HEADER header[2] = (uint) ( DDS_HEADER_FLAGS.DDSD_CAPS | DDS_HEADER_FLAGS.DDSD_HEIGHT | DDS_HEADER_FLAGS.DDSD_WIDTH | DDS_HEADER_FLAGS.DDSD_PIXELFORMAT | (format == UnityCompatibleFormat.DXT1 || format == UnityCompatibleFormat.DXT5 || format == UnityCompatibleFormat.BC7 ? DDS_HEADER_FLAGS.DDSD_LINEARSIZE : 0) | (mipMaps > 0 ? DDS_HEADER_FLAGS.DDSD_MIPMAPCOUNT : 0) ); header[3] = (uint)height; header[4] = (uint)width; header[5] = (header[2] & (uint)DDS_HEADER_FLAGS.DDSD_LINEARSIZE) != 0 ? (uint)(Math.Max(1, ((width + 3) / 4)) * (format == UnityCompatibleFormat.DXT1 ? 2 : 4) /*block_size*/ * height) : 0; header[7] = mipMaps > 0 ? (uint)mipMaps : 0; header[19] = 32; // sizeof DDS_PIXELFORMAT header[20] = (uint) ( format == UnityCompatibleFormat.DXT1 || format == UnityCompatibleFormat.DXT5 || format == UnityCompatibleFormat.RGBAFloat || format == UnityCompatibleFormat.RGBAHalf || format == UnityCompatibleFormat.BC7 ? DDS_PIXEL_FORMAT.DDPF_FOURCC : format == UnityCompatibleFormat.Alpha8 ? DDS_PIXEL_FORMAT.DDPF_ALPHA : DDS_PIXEL_FORMAT.DDPF_RGB | ( format == UnityCompatibleFormat.RGBA32 || format == UnityCompatibleFormat.ARGB32 ? DDS_PIXEL_FORMAT.DDPF_ALPHAPIXELS : 0 ) ); header[21] = fourCC; header[22] = (uint)rgbBitCount; if ((header[20] & (uint)DDS_PIXEL_FORMAT.DDPF_RGB) != 0) { if (format != UnityCompatibleFormat.Alpha8) { header[23] = 0x00ff0000; header[24] = 0x0000ff00; header[25] = 0x000000ff; header[26] = rgbBitCount >= 32 ? 0xff000000 : 0; } else { header[26] = 0xff; } } header[27] = (uint)(DDS_CAPS.DDSCAPS_TEXTURE | (mipMaps > 0 ? DDS_CAPS.DDSCAPS_COMPLEX | DDS_CAPS.DDSCAPS_MIPMAP : 0)); if (cubemap) { header[28] = (uint)(DDS_CAPS2.DDSCAPS2_CUBEMAP | DDS_CAPS2.DDS_CUBEMAP_ALLFACES); } if (/*format == UnityCompatibleFormat.RGBAFloat || format == UnityCompatibleFormat.RGBAHalf || */format == UnityCompatibleFormat.BC7) { header[32] = //format == UnityCompatibleFormat.RGBAFloat ? (uint)SlimDX.Direct3D9.Format.A32B32G32R32F : (uint)SlimDX.Direct3D9.Format.A16B16G16R16F; (uint)SlimDX.DXGI.Format.BC7_UNorm; header[33] = (uint)ResourceDimension.Texture2D; header[35] = 1; } return(ConvertToByteArray(header)); }
public static byte[] CreateHeader(int width, int height, byte pixelDepth, UnityCompatibleFormat format) { int row_size = (pixelDepth * width + 31) / 32 * 4; byte[] bmp_header = new byte[0x0e + 40 + (pixelDepth == 16 || pixelDepth == 32 ? 16 : 0)]; using (BinaryWriter writer = new BinaryWriter(new MemoryStream(bmp_header))) { writer.Write((byte)'B'); writer.Write((byte)'M'); writer.Write((uint)((row_size * height) + bmp_header.Length)); writer.BaseStream.Position = 0xA; writer.Write((uint)bmp_header.Length); writer.Write((uint)(bmp_header.Length - 0x0e)); writer.Write(width); writer.Write(height); writer.Write((ushort)1); writer.Write((ushort)pixelDepth); if (bmp_header.Length > 0x0e + 40) { writer.Write((uint)3); // compression: BI_BITFIELDS writer.Write((uint)(row_size * height)); writer.BaseStream.Position = 0x36; if (format == UnityCompatibleFormat.ARGB32) { writer.Write((uint)0xFF000000); writer.Write((uint)0x00FF0000); writer.Write((uint)0x0000FF00); writer.Write((uint)0x000000FF); } else if (format == UnityCompatibleFormat.RGBA32) { writer.Write((uint)0x000000FF); writer.Write((uint)0x0000FF00); writer.Write((uint)0x00FF0000); writer.Write((uint)0xFF000000); } } } return(bmp_header); }