public BitmapControl(GameCache cache, TagTool.Tags.Definitions.Bitmap bitmap) : this() { Cache = cache; Bitmap = bitmap; Bitmap result = null; var transparent = false; // Create a DevIL image "name" (which is actually a number) int img_name; try { DevIL.ilGenImages(1, out img_name); } catch { return; } DevIL.ilBindImage(img_name); var ddsData = BitmapExtractor.ExtractBitmapToDDSArray(cache, Bitmap, 0); // Load the DDS file into the bound DevIL image DevIL.ilLoadL(DevIL.IL_DDS, ddsData, ddsData.Length); // Set a few size variables that will simplify later code int width = DevIL.ilGetInteger(DevIL.IL_IMAGE_WIDTH); int height = DevIL.ilGetInteger(DevIL.IL_IMAGE_HEIGHT); var rect = new System.Drawing.Rectangle(0, 0, width, height); pictureBox1.Size = new Size(Math.Min(512, width), Math.Min(512, height)); //imagesComboBox.Width = pictureBox1.Width; // Convert the DevIL image to a pixel byte array to copy into Bitmap DevIL.ilConvertImage(DevIL.IL_BGRA, DevIL.IL_UNSIGNED_BYTE); // Create a Bitmap to copy the image into, and prepare it to get data result = new Bitmap(width, height); var pixelData = result.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // Copy the pixel byte array from the DevIL image to the Bitmap DevIL.ilCopyPixels(0, 0, 0, DevIL.ilGetInteger(DevIL.IL_IMAGE_WIDTH), DevIL.ilGetInteger(DevIL.IL_IMAGE_HEIGHT), 1, DevIL.IL_BGRA, DevIL.IL_UNSIGNED_BYTE, pixelData.Scan0); // Clean up and return Bitmap DevIL.ilDeleteImages(1, ref img_name); result.UnlockBits(pixelData); var format = Bitmap.Images[0].Format; if (!transparent) { transparent = //format == BitmapFormat.Dxn || format == TagTool.Bitmaps.BitmapFormat.DxnMonoAlpha || format == TagTool.Bitmaps.BitmapFormat.A8 || format == TagTool.Bitmaps.BitmapFormat.AY8 || format == TagTool.Bitmaps.BitmapFormat.A8Y8 || format == TagTool.Bitmaps.BitmapFormat.A8R8G8B8 || format == TagTool.Bitmaps.BitmapFormat.A16B16G16R16 || format == TagTool.Bitmaps.BitmapFormat.A16B16G16R16F || format == TagTool.Bitmaps.BitmapFormat.A1R5G5B5 || format == TagTool.Bitmaps.BitmapFormat.A2R10G10B10 || format == TagTool.Bitmaps.BitmapFormat.A32B32G32R32F || format == TagTool.Bitmaps.BitmapFormat.A4R4G4B4 || format == TagTool.Bitmaps.BitmapFormat.A4R4G4B4Font; } pictureBox1.Image = result; }
public RenderTexture(D3DDevice device, HaloOnlineCacheContext cacheContext, TagTool.Tags.Definitions.Bitmap bitmapDefinition, int imageIndex = 0) { Bitmap = bitmapDefinition; var extractor = new TagTool.Bitmaps.BitmapDdsExtractor(cacheContext); var transparent = false; Bitmap bitmap = null; using (var ddsStream = new MemoryStream()) { extractor.ExtractDds(bitmapDefinition, 0, ddsStream); ddsStream.Position = 0; // Create a DevIL image "name" (which is actually a number) DevIL.ilGenImages(1, out int img_name); DevIL.ilBindImage(img_name); var ddsData = ddsStream.ToArray(); // Load the DDS file into the bound DevIL image DevIL.ilLoadL(DevIL.IL_DDS, ddsData, ddsData.Length); // Set a few size variables that will simplify later code int width = DevIL.ilGetInteger(DevIL.IL_IMAGE_WIDTH); int height = DevIL.ilGetInteger(DevIL.IL_IMAGE_HEIGHT); var rect = new System.Drawing.Rectangle(0, 0, width, height); // Convert the DevIL image to a pixel byte array to copy into Bitmap DevIL.ilConvertImage(DevIL.IL_BGRA, DevIL.IL_UNSIGNED_BYTE); // Create a Bitmap to copy the image into, and prepare it to get data bitmap = new Bitmap(width, height); var pixelData = bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); // Copy the pixel byte array from the DevIL image to the Bitmap DevIL.ilCopyPixels(0, 0, 0, DevIL.ilGetInteger(DevIL.IL_IMAGE_WIDTH), DevIL.ilGetInteger(DevIL.IL_IMAGE_HEIGHT), 1, DevIL.IL_BGRA, DevIL.IL_UNSIGNED_BYTE, pixelData.Scan0); // Clean up and return Bitmap DevIL.ilDeleteImages(1, ref img_name); bitmap.UnlockBits(pixelData); var format = bitmapDefinition.Images[imageIndex].Format; if (!transparent) { transparent = //format == BitmapFormat.Dxn || format == TagTool.Bitmaps.BitmapFormat.DxnMonoAlpha || format == TagTool.Bitmaps.BitmapFormat.A8 || format == TagTool.Bitmaps.BitmapFormat.AY8 || format == TagTool.Bitmaps.BitmapFormat.A8Y8 || format == TagTool.Bitmaps.BitmapFormat.A8R8G8B8 || format == TagTool.Bitmaps.BitmapFormat.A16B16G16R16 || format == TagTool.Bitmaps.BitmapFormat.A16B16G16R16F || format == TagTool.Bitmaps.BitmapFormat.A1R5G5B5 || format == TagTool.Bitmaps.BitmapFormat.A2R10G10B10 || format == TagTool.Bitmaps.BitmapFormat.A32B32G32R32F || format == TagTool.Bitmaps.BitmapFormat.A4R4G4B4 || format == TagTool.Bitmaps.BitmapFormat.A4R4G4B4Font; } } Texture = new Texture(device, bitmap.Width, bitmap.Height, 1, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed); var bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var textureData = Texture.LockRectangle(0, LockFlags.None, out var pitch); unsafe { int *texturePointer = (int *)textureData.InternalData; for (var i = 0; i < bitmap.Height; i++) { var bitmapLinePointer = (int *)bitmapData.Scan0 + i * (bitmapData.Stride / sizeof(int)); var textureLinePointer = texturePointer + i * (pitch / sizeof(int)); var length = bitmap.Width; while (--length >= 0) { *textureLinePointer++ = *bitmapLinePointer++; } } } bitmap.UnlockBits(bitmapData); Texture.UnlockRectangle(0); Texture.GenerateMipSubLevels(); Texture.AutoGenerateFilterType = TextureFilter.Linear; }
unsafe void loadAndGrabMip(string filename, int mipToGrab) { try { bool bCacheBitmaps = false; bool bCacheDXT = true; System.IO.FileInfo fileInfo = new System.IO.FileInfo(filename); ImageInformation imageInfo = TextureLoader.ImageInformationFromFile(filename); Format desiredFormat = Format.X8R8G8B8; if (mFilename.EndsWith("_op.tga") || mFilename.EndsWith("_xf.tga")) { desiredFormat = Format.L8; } int desiredWidth = imageInfo.Width >> mipToGrab; int desiredHeight = imageInfo.Height >> mipToGrab; if (desiredFormat == Format.X8R8G8B8) { if (desiredWidth < 16 && desiredHeight < 16) { mTexture = TextureLoader.FromFile(BRenderDevice.getDevice(), filename, desiredWidth, desiredHeight, 1, 0, desiredFormat, Pool.Managed, Filter.Box, Filter.Box, 0); TextureStats.mSmallTextureSize += fileInfo.Length; } else { Image img; Bitmap bmr; string cachedDXTName = filename.Replace("\\work\\art\\", "\\work\\artcache\\"); cachedDXTName = Path.ChangeExtension(cachedDXTName, ".dxt"); long dxtFileLen = 0; bool bLoadFromCache = false; if (bCacheDXT && File.Exists(cachedDXTName)) { System.IO.FileInfo dxtFileInfo = new System.IO.FileInfo(cachedDXTName); dxtFileLen = dxtFileInfo.Length; if (dxtFileInfo.LastWriteTimeUtc >= fileInfo.LastWriteTimeUtc) { bLoadFromCache = true; //DXT exists and is current } } if (bLoadFromCache == false) { string cacheDir = Path.GetDirectoryName(cachedDXTName); if ((bCacheDXT || bCacheBitmaps) && Directory.Exists(cacheDir) == false) { Directory.CreateDirectory(cacheDir); } //if (!bCacheBitmaps || mipToGrab == 0) { lock (DevIL.sSyncRoot) { img = DevIL.LoadImageFromFile(filename); bmr = new Bitmap(img, desiredWidth, desiredHeight); } TextureStats.mLargeTextureSizes += fileInfo.Length; TextureStats.mRaw += fileInfo.Length; } //else //{ // string cachedBMPName = filename.Replace("\\work\\art\\", "\\work\\artcache\\"); // cachedBMPName = Path.ChangeExtension(cachedBMPName, ".bmp"); // if (File.Exists(cachedBMPName) == false) // { // TextureStats.mLargeTextureSizes += fileInfo.Length; // lock (DevIL.sSyncRoot) // { // img = DevIL.LoadImageFromFile(filename); // bmr = new Bitmap(img, desiredWidth, desiredHeight); // } // bmr.Save(cachedBMPName, ImageFormat.Bmp); // System.IO.FileInfo tfileInfo = new System.IO.FileInfo(cachedBMPName); // TextureStats.mCCreate += tfileInfo.Length; // } // else // { // System.IO.FileInfo tfileInfo = new System.IO.FileInfo(cachedBMPName); // TextureStats.mLargeTextureSizes += tfileInfo.Length; // lock (DevIL.sSyncRoot) // { // img = DevIL.LoadImageFromFile(cachedBMPName); // bmr = new Bitmap(img, desiredWidth, desiredHeight); // } // } //} Rectangle r = new Rectangle(0, 0, desiredWidth, desiredHeight); BitmapData sourceData = bmr.LockBits(r, ImageLockMode.ReadOnly, bmr.PixelFormat); byte *pInData = (byte *)sourceData.Scan0; int size = 0; // byte[] pko = new byte[desiredWidth * desiredHeight * 4]; // fixed (byte* pPko = pko) //DXT_CLI.compressDXT(pInData, desiredWidth, desiredHeight, 1, pPko, &size); mTexture = new Texture(BRenderDevice.getDevice(), desiredWidth, desiredHeight, 1, Usage.None, Format.Dxt1, Pool.Managed); GraphicsStream gsOut = mTexture.LockRectangle(0, LockFlags.None); byte * pOutData = (byte *)gsOut.InternalDataPointer; DXT_CLI.compressDXT(pInData, desiredWidth, desiredHeight, 1, pOutData, &size); // for (int i = 0; i < size; i++) // pOutData[i] = pko[i]; if (bCacheDXT) { byte[] byteArrayName = new byte[size]; Marshal.Copy(new IntPtr(pOutData), byteArrayName, 0, size); BinaryWriter wr = new BinaryWriter(new FileStream(cachedDXTName, FileMode.Create)); wr.Write(size); wr.Write(byteArrayName, 0, size); wr.Close(); TextureStats.mCCreate += size; } mTexture.UnlockRectangle(0); bmr.UnlockBits(sourceData); gsOut = null; pOutData = null; bmr = null; pInData = null; img = null; //pko = null; } else //Load DXT from cached file { BinaryReader r = new BinaryReader(new FileStream(cachedDXTName, FileMode.Open)); int size; size = r.ReadInt32(); if (size != (desiredWidth * desiredHeight * 0.5)) { r.Close(); File.Delete(cachedDXTName); loadAndGrabMip(filename, mipToGrab); return; } byte[] byteArrayName = new byte[size]; r.Read(byteArrayName, 0, size); //long bytesread = r.BaseStream.Position; r.Close(); //byte* pByteArrayName = stackalloc byte[size]; //IntPtr pByteArrayName = Marshal.AllocHGlobal(size); //Marshal.Copy(byteArrayName, 0, pByteArrayName, size); TextureStats.mLargeTextureSizes += size; TextureStats.mCLoad += size; mTexture = new Texture(BRenderDevice.getDevice(), desiredWidth, desiredHeight, 1, Usage.None, Format.Dxt1, Pool.Managed); GraphicsStream gsOut = mTexture.LockRectangle(0, LockFlags.None); byte * pOutData = (byte *)gsOut.InternalDataPointer; Marshal.Copy(byteArrayName, 0, (IntPtr)pOutData, size); //byte* pBytes = (byte*)(pByteArrayName.ToPointer()); //for (int i = 0; i < size; i++) //{ // pOutData[i] = pBytes[i]; //} mTexture.UnlockRectangle(0); } } } else if (desiredFormat == Format.L8) { mTexture = TextureLoader.FromFile(BRenderDevice.getDevice(), filename, desiredWidth, desiredHeight, 1, 0, desiredFormat, Pool.Managed, Filter.Box, Filter.Box, 0); TextureStats.mL16FileSize += fileInfo.Length; } else { Debug.Assert(false); } } catch (OutOfVideoMemoryException ve) { MessageBox.Show("Out of video memory.. Talk to the editor guys.."); } catch (OutOfMemoryException me) { MessageBox.Show("Out of System memory.. Talk to the editor guys.."); } }