/// <summary> /// Compresses the specified image. /// </summary> /// <param name="image">The image.</param> /// <param name="libraryData">The library data.</param> /// <param name="request">The request.</param> /// <exception cref="TextureToolsException">Compression failed</exception> private void Compress(TexImage image, DxtTextureLibraryData libraryData, CompressingRequest request) { Log.Debug("Converting/Compressing with " + request.Format + " ..."); if (libraryData.DxtImages == null || libraryData.DxtImages.Length == 0) { return; } ScratchImage scratchImage = new ScratchImage(); HRESULT hr; if (request.Format.IsCompressed()) { var topImage = libraryData.DxtImages[0]; if (topImage.Width % 4 != 0 || topImage.Height % 4 != 0) { throw new TextureToolsException(string.Format("The provided texture cannot be compressed into format '{0}' " + "because its top resolution ({1}-{2}) is not a multiple of 4.", request.Format, topImage.Width, topImage.Height)); } hr = Utilities.Compress(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, RetrieveNativeFormat(request.Format), TEX_COMPRESS_FLAGS.TEX_COMPRESS_DEFAULT, 0.5f, scratchImage); } else { hr = Utilities.Convert(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, RetrieveNativeFormat(request.Format), TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT, 0.5f, scratchImage); } if (hr != HRESULT.S_OK) { Log.Error("Compression failed: " + hr); throw new TextureToolsException("Compression failed: " + hr); } if (image.DisposingLibrary != null) { image.DisposingLibrary.Dispose(image); } // Updating attributes libraryData.Image = scratchImage; libraryData.DxtImages = libraryData.Image.GetImages(); libraryData.Metadata = libraryData.Image.metadata; image.DisposingLibrary = this; UpdateImage(image, libraryData); }
private static void checkIsDisposedWhenAlive(WeakReference weakRef2, bool expected) { ScratchImage mips = weakRef2.Target as ScratchImage; if (mips != null) { // although unlikely but the GC might have already collected it Assert.AreEqual(expected, mips.IsDisposed); } else { Console.WriteLine("Mips was already collected by GC"); } }
public static unsafe byte[] Convert(Byte[] data, int width, int height, DXGI_FORMAT inputFormat, DXGI_FORMAT outputFormat) { long inputRowPitch; long inputSlicePitch; TexHelper.Instance.ComputePitch(inputFormat, width, height, out inputRowPitch, out inputSlicePitch, CP_FLAGS.NONE); if (data.Length == inputSlicePitch) { byte *buf; buf = (byte *)Marshal.AllocHGlobal((int)inputSlicePitch); Marshal.Copy(data, 0, (IntPtr)buf, (int)inputSlicePitch); DirectXTexNet.Image inputImage = new DirectXTexNet.Image( width, height, inputFormat, inputRowPitch, inputSlicePitch, (IntPtr)buf, null); TexMetadata texMetadata = new TexMetadata(width, height, 1, 1, 1, 0, 0, inputFormat, TEX_DIMENSION.TEXTURE2D); ScratchImage scratchImage = TexHelper.Instance.InitializeTemporary( new DirectXTexNet.Image[] { inputImage }, texMetadata, null); var convFlags = TEX_FILTER_FLAGS.DEFAULT; if (inputFormat == DXGI_FORMAT.B8G8R8A8_UNORM_SRGB || inputFormat == DXGI_FORMAT.B8G8R8X8_UNORM_SRGB || inputFormat == DXGI_FORMAT.R8G8B8A8_UNORM_SRGB) { convFlags |= TEX_FILTER_FLAGS.SRGB; } using (var decomp = scratchImage.Convert(0, outputFormat, convFlags, 0.5f)) { long outRowPitch; long outSlicePitch; TexHelper.Instance.ComputePitch(outputFormat, width, height, out outRowPitch, out outSlicePitch, CP_FLAGS.NONE); byte[] result = new byte[outSlicePitch]; Marshal.Copy(decomp.GetImage(0).Pixels, result, 0, result.Length); inputImage = null; scratchImage.Dispose(); return(result); } } return(null); }
public static unsafe byte[] DecompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format) { Console.WriteLine(format); long inputRowPitch; long inputSlicePitch; TexHelper.Instance.ComputePitch((DXGI_FORMAT)format, width, height, out inputRowPitch, out inputSlicePitch, CP_FLAGS.NONE); DXGI_FORMAT FormatDecompressed; if (format.ToString().Contains("SRGB")) { FormatDecompressed = DXGI_FORMAT.R8G8B8A8_UNORM_SRGB; } else { FormatDecompressed = DXGI_FORMAT.R8G8B8A8_UNORM; } if (data.Length == inputSlicePitch) { byte *buf; buf = (byte *)Marshal.AllocHGlobal((int)inputSlicePitch); Marshal.Copy(data, 0, (IntPtr)buf, (int)inputSlicePitch); DirectXTexNet.Image inputImage = new DirectXTexNet.Image( width, height, (DXGI_FORMAT)format, inputRowPitch, inputSlicePitch, (IntPtr)buf, null); TexMetadata texMetadata = new TexMetadata(width, height, 1, 1, 1, 0, 0, (DXGI_FORMAT)format, TEX_DIMENSION.TEXTURE2D); ScratchImage scratchImage = TexHelper.Instance.InitializeTemporary( new DirectXTexNet.Image[] { inputImage }, texMetadata, null); using (var decomp = scratchImage.Decompress(0, FormatDecompressed)) { byte[] result = new byte[4 * width * height]; Marshal.Copy(decomp.GetImage(0).Pixels, result, 0, result.Length); inputImage = null; scratchImage.Dispose(); return(result); } } return(null); }
/// <summary> /// Splits Color and Spec from IW /// </summary> private void SplitCSIW(string imagePath, string extension, ScratchImage.DXGIFormat outFormat, string outputPath = null) { using (var inputImage = new ScratchImage(imagePath)) { // Force the image to a standard format inputImage.ConvertImage(ScratchImage.DXGIFormat.R8G8B8A8UNORM); var inputPixels = inputImage.GetPixels(); var colorPixels = new byte[inputPixels.Length]; var specPixels = new byte[inputPixels.Length]; for (int i = 0; i < inputPixels.Length; i += 4) { // Obtain the "Mask" from the Alpha Channel as a multiplier // with our color mask being the remainder var specMask = inputPixels[i + 3] / 255.0; var colorMask = 1.0 - specMask; // Color Values colorPixels[i + 0] = (byte)(inputPixels[i + 0] * colorMask); colorPixels[i + 1] = (byte)(inputPixels[i + 1] * colorMask); colorPixels[i + 2] = (byte)(inputPixels[i + 2] * colorMask); colorPixels[i + 3] = 255; // Spec Values specPixels[i + 0] = Helpers.Clamp <byte>((byte)(inputPixels[i + 0] * specMask), 255, 56); specPixels[i + 1] = Helpers.Clamp <byte>((byte)(inputPixels[i + 1] * specMask), 255, 56); specPixels[i + 2] = Helpers.Clamp <byte>((byte)(inputPixels[i + 2] * specMask), 255, 56); specPixels[i + 3] = 255; } if (outputPath == null) { outputPath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath).Split(new string[] { "_c&", "_c_" }, StringSplitOptions.None)[0]); } using (var color = new ScratchImage(inputImage.Metadata, colorPixels)) using (var spec = new ScratchImage(inputImage.Metadata, specPixels)) { if (extension == ".dds") { color.ConvertImage(outFormat); spec.ConvertImage(outFormat); } color.Save(outputPath + "_c" + extension); spec.Save(outputPath + "_s" + extension); } } }
public void Dispose(TexImage image) { DxtTextureLibraryData libraryData = (DxtTextureLibraryData)image.LibraryData[this]; if (libraryData.Image == null && libraryData.DxtImages != null) { ScratchImage img = new ScratchImage(); img.InitializeFromImages(libraryData.DxtImages, libraryData.DxtImages.Length); img.Release(); } else { libraryData.Image.Dispose(); } }
private ScratchImage createTempFromMips(ScratchImage orig, out WeakReference weak, bool takeOwnership) { var mips = orig.GenerateMipMaps(TEX_FILTER_FLAGS.FANT, 0); weak = new WeakReference(mips); Size_t count = mips.GetImageCount(); Image[] arr = new Image[count]; for (Size_t i = 0; i < count; i++) { arr[i] = mips.GetImage(i); } return(TexHelper.Instance.InitializeTemporary(arr, mips.GetMetadata(), takeOwnership ? new IDisposable[] { mips } : null)); }
private void AssertEqual(ScratchImage image, Bitmap expected) { // Check various meta-data. var metaData = image.GetMetadata(); AssertEqual(metaData, expected); // Check raw contents match. (This test only works for specific images) var img = image.GetImage(0); var expectedBytes = expected.GetRawBytesRGBA(); var readBytes = new byte[expectedBytes.Length]; Marshal.Copy(img.Pixels, readBytes, 0, readBytes.Length); Assert.That(readBytes, Is.EqualTo(expectedBytes)); }
public override void ImportImage(string filename) { // Import // Se le va a pasar un png y hay que convertirlo al formato de la DDS using (ScratchImage originalDds = DirectXTexNet.TexHelper.Instance.LoadFromDDSFile(Path, DDS_FLAGS.NONE)) { TexMetadata originalMetadata = originalDds.GetMetadata(); ScratchImage png = DirectXTexNet.TexHelper.Instance.LoadFromWICFile(filename, WIC_FLAGS.NONE); var compareTask = CompareImagesAsync(originalDds, png); var areEqual = compareTask.WaitAndUnwrapException(); if (areEqual) { png.Dispose(); return; } if (originalMetadata.MipLevels > 1) { ScratchImage aux = png.GenerateMipMaps(TEX_FILTER_FLAGS.DEFAULT, originalMetadata.MipLevels); png.Dispose(); png = aux; } if (IsCompressed(originalMetadata.Format)) { DXGI_FORMAT format = originalMetadata.Format; if (format == DXGI_FORMAT.BC7_UNORM_SRGB) { format = DXGI_FORMAT.BC7_UNORM; } using (ScratchImage newDds = png.Compress(format, TEX_COMPRESS_FLAGS.PARALLEL, 0.5f)) { newDds.SaveToDDSFile(DDS_FLAGS.NONE, ChangesFile); } } else { png.SaveToDDSFile(DDS_FLAGS.NONE, ChangesFile); } png?.Dispose(); } }
protected virtual ScratchImage GetScratchImage() { string source = HasChanges ? ChangesFile : Path; ScratchImage img = TexHelper.Instance.LoadFromDDSFile(source, DDS_FLAGS.NONE); TexMetadata metadata = img.GetMetadata(); if (IsCompressed(metadata.Format)) { ScratchImage tmp = img.Decompress(DXGI_FORMAT.UNKNOWN); img.Dispose(); img = tmp; } return(img); }
/// <summary> /// Splits by color and alpha /// </summary> private void SplitColorAlpha(string imagePath, string extension, ScratchImage.DXGIFormat outFormat, string outputPath = null) { using (var inputImage = new ScratchImage(imagePath)) { // Force the image to a standard format inputImage.ConvertImage(ScratchImage.DXGIFormat.R8G8B8A8UNORM); var inputPixels = inputImage.GetPixels(); var colorPixels = new byte[inputPixels.Length]; var alphaPixels = new byte[inputPixels.Length]; for (int i = 0; i < inputPixels.Length; i += 4) { // Copy Gloss colorPixels[i + 0] = inputPixels[i + 0]; colorPixels[i + 1] = inputPixels[i + 1]; colorPixels[i + 2] = inputPixels[i + 2]; colorPixels[i + 3] = 0xFF; // Compute Normal Map (Only XY is stored) alphaPixels[i + 0] = inputPixels[i + 3]; alphaPixels[i + 1] = inputPixels[i + 3]; alphaPixels[i + 2] = inputPixels[i + 3]; alphaPixels[i + 3] = 0xFF; } if (outputPath == null) { outputPath = Path.Combine( Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath).Split(new string[] { "&" }, StringSplitOptions.None)[0].Replace("-", "_").Replace("~", "")); } using (var color = new ScratchImage(inputImage.Metadata, colorPixels)) using (var alpha = new ScratchImage(inputImage.Metadata, alphaPixels)) { if (extension == ".dds") { color.ConvertImage(outFormat); alpha.ConvertImage(outFormat); } color.Save(outputPath + "_s" + extension); alpha.Save(outputPath + "_g" + extension); } } }
public void Finalizers() { var path = GetImagePath("ThisIsATest.tga"); using (var image = TexHelper.Instance.LoadFromTGAFile(path)) { // create Mips within other method call and wrap its image with TempScratchImages WeakReference weakRef1; WeakReference weakRef2; ScratchImage temp1 = this.createTempFromMips(image, out weakRef1, false); ScratchImage temp2 = this.createTempFromMips(image, out weakRef2, true); // check if the mips have not been finalized GC.Collect(); GC.WaitForPendingFinalizers(); Assert.True(weakRef1.IsAlive); Assert.True(weakRef2.IsAlive); // dispose temp2 (has ownerships of it's mips) temp2.Dispose(); // because ownership was transferred, it's mips should be disposed checkIsDisposedWhenAlive(weakRef2, true); // check if temp1 still prevents it's mips from being finalized // the mips of temp2 will be collected by the garbage collector GC.Collect(); GC.WaitForPendingFinalizers(); Assert.True(weakRef1.IsAlive); Assert.False(weakRef2.IsAlive); // now temp1 is disposed temp1.Dispose(); // because ownership was not transferred, it's mips should not be disposed yet, if the GC has not run checkIsDisposedWhenAlive(weakRef1, false); // but calling GC, should dispose the mips at last GC.Collect(); GC.WaitForPendingFinalizers(); Assert.False(weakRef1.IsAlive); Assert.False(weakRef2.IsAlive); } }
public override void ExportImage(string filename) { if (_currentDDS != null && !_currentDDS.IsDisposed) { _currentDDS.Dispose(); _currentDDS = null; } _currentDDS = GetScratchImage(); string directory = System.IO.Path.GetDirectoryName(filename); Directory.CreateDirectory(directory); _currentDDS.SaveToDDSFile(DDS_FLAGS.NONE, filename); _currentDDS.Dispose(); _currentDDS = null; }
/// <summary> /// Converts the given image to any format /// </summary> private void ConvertImage(string imagePath, string extension, ScratchImage.DXGIFormat outFormat, string outputPath = null) { using (var image = new ScratchImage(imagePath)) { // Force the image to a standard format image.ConvertImage(ScratchImage.DXGIFormat.R8G8B8A8UNORM); if (outputPath == null) { outputPath = Path.Combine(Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath)); } if (extension == ".dds") { image.ConvertImage(outFormat); } image.Save(outputPath + extension); } }
private void Decompress(ref ScratchImage scratch) { var meta = scratch.GetMetadata(); ScratchImage decompressed; switch (meta.Format) { case DXGI_FORMAT.BC1_TYPELESS: case DXGI_FORMAT.BC1_UNORM: case DXGI_FORMAT.BC1_UNORM_SRGB: case DXGI_FORMAT.BC2_TYPELESS: case DXGI_FORMAT.BC2_UNORM: case DXGI_FORMAT.BC2_UNORM_SRGB: case DXGI_FORMAT.BC3_TYPELESS: case DXGI_FORMAT.BC3_UNORM: case DXGI_FORMAT.BC3_UNORM_SRGB: case DXGI_FORMAT.BC4_TYPELESS: case DXGI_FORMAT.BC4_UNORM: case DXGI_FORMAT.BC4_SNORM: case DXGI_FORMAT.BC5_TYPELESS: case DXGI_FORMAT.BC5_UNORM: case DXGI_FORMAT.BC5_SNORM: case DXGI_FORMAT.BC6H_TYPELESS: case DXGI_FORMAT.BC6H_UF16: case DXGI_FORMAT.BC6H_SF16: case DXGI_FORMAT.BC7_TYPELESS: case DXGI_FORMAT.BC7_UNORM: case DXGI_FORMAT.BC7_UNORM_SRGB: decompressed = scratch.Decompress(DXGI_FORMAT.B8G8R8A8_UNORM); break; default: decompressed = scratch.Convert(DXGI_FORMAT.B8G8R8A8_UNORM, TEX_FILTER_FLAGS.FANT, 0.5f); break; } scratch.Dispose(); scratch = decompressed; }
protected override Tuple <Image, object> GetImage() { var source = HasChanges ? ChangesFile : Path; _currentDDS = TexHelper.Instance.LoadFromDDSFile(source, DDS_FLAGS.NONE); var codec = TexHelper.Instance.GetWICCodec(WICCodecs.PNG); var metadata = _currentDDS.GetMetadata(); ScratchImage decompressed; try { decompressed = _currentDDS.Decompress(DXGI_FORMAT.UNKNOWN); } catch (ArgumentException e) { decompressed = _currentDDS; } try { var imageStream = decompressed.SaveToWICMemory(0, WIC_FLAGS.NONE, codec); decompressed.Dispose(); var image = Image.FromStream(imageStream); var properties = new TexMetadataView(metadata); return(new Tuple <Image, object>(image, properties)); } catch (Exception e) { return(new Tuple <Image, object>(null, null)); } }
private void Button_Click(object sender, RoutedEventArgs e) { string choice = (string)((ComboBoxItem)ResolutionChoice.SelectedItem).Content; string[] parts = choice.Split('x'); int width, height; int.TryParse(parts[0], out width); int.TryParse(parts[1], out height); if (image.GetMetadata().Width != width || image.GetMetadata().Height != height) { image = image.Resize(width, height, TEX_FILTER_FLAGS.DEFAULT); } image = image.TransformImage(changeAlpha); if (BC3.IsChecked == true) { image = image.Compress(DXGI_FORMAT.BC3_UNORM, TEX_COMPRESS_FLAGS.DEFAULT, 0.5f); } else if (BC7.IsChecked == true) { image = convertBC7(image); } string textureDir = getFullPath("work/textures/sky"); System.IO.Directory.CreateDirectory(textureDir); image.SaveToDDSFile(DDS_FLAGS.NONE, textureDir + "/skyrimgalaxy.dds"); image.Dispose(); string folder = getFullPath("work"); string target = getFullPath("UltraHiResNightsky.zip"); ZipFile.CreateFromDirectory(folder, target, CompressionLevel.Fastest, false); Close(); }
/* Import a file to replace the selected PAK entry */ private void ImportSelectedFile() { if (FileTree.SelectedNode == null || ((TreeItem)FileTree.SelectedNode.Tag).Item_Type != TreeItemType.EXPORTABLE_FILE) { MessageBox.Show("Please select a file from the list.", "No file selected.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //If import file is DDS, check first to see if it can be imported as WIC format string filter = "Import File|*" + Path.GetExtension(FileTree.SelectedNode.Text); DXGI_FORMAT baseFormat = DXGI_FORMAT.UNKNOWN; if (Path.GetExtension(FileTree.SelectedNode.Text).ToUpper() == ".DDS") { byte[] ImageFile = GetFileAsBytes(((TreeItem)FileTree.SelectedNode.Tag).String_Value); try { ScratchImage img = TexHelper.Instance.LoadFromDDSMemory(Marshal.UnsafeAddrOfPinnedArrayElement(ImageFile, 0), ImageFile.Length, DDS_FLAGS.NONE); baseFormat = img.GetMetadata().Format; if (baseFormat != DXGI_FORMAT.UNKNOWN) { filter = "PNG Image|*.png|DDS Image|*.dds"; //Can import as WIC } } catch { } } //Allow selection of a file (force extension), then drop it in OpenFileDialog FilePicker = new OpenFileDialog(); FilePicker.Filter = filter; if (FilePicker.ShowDialog() == DialogResult.OK) { Cursor.Current = Cursors.WaitCursor; //Special import for DDS conversion bool ImportOK = true; bool ImportingConverted = false; if (baseFormat != DXGI_FORMAT.UNKNOWN && Path.GetExtension(FilePicker.FileName).ToUpper() == ".PNG") { try { ScratchImage img = TexHelper.Instance.LoadFromWICFile(FilePicker.FileName, WIC_FLAGS.FORCE_RGB).GenerateMipMaps(TEX_FILTER_FLAGS.DEFAULT, 10); /* Was using 11, but gives remainders - going for 10 */ ScratchImage imgDecom = img.Compress(DXGI_FORMAT.BC7_UNORM, TEX_COMPRESS_FLAGS.BC7_QUICK, 0.5f); //TODO use baseFormat imgDecom.SaveToDDSFile(DDS_FLAGS.FORCE_DX10_EXT, FilePicker.FileName + ".DDS"); FilePicker.FileName += ".DDS"; ImportingConverted = true; } catch (Exception e) { //MessageBox.Show(e.ToString()); ImportOK = false; MessageBox.Show("Failed to import as PNG!\nPlease try again as DDS.", AlienErrors.ErrorMessageTitle(PAKReturnType.FAIL_UNKNOWN), MessageBoxButtons.OK, MessageBoxIcon.Information); } } //Regular import if (ImportOK) { foreach (PAK thisPAK in AlienPAKs) { thisPAK.ImportFile(((TreeItem)FileTree.SelectedNode.Tag).String_Value, FilePicker.FileName); } if (ImportingConverted) { File.Delete(FilePicker.FileName); //We temp dump out a converted file, which this cleans up } MessageBox.Show(AlienErrors.ErrorMessageBody(PAKReturnType.SUCCESS), AlienErrors.ErrorMessageTitle(PAKReturnType.SUCCESS), MessageBoxButtons.OK, MessageBoxIcon.Information); } Cursor.Current = Cursors.Default; } UpdateSelectedFilePreview(); }
public static byte[] ConvertDDS(GUIDEntry value, DXGI_FORMAT targetFormat, ImageFormat imageFormat, int frame) { try { if (GetDataType(value) != DataType.Image) { return(null); } teTexture texture = new teTexture(IOHelper.OpenFile(value)); if (texture.PayloadRequired) { ulong payload = texture.GetPayloadGUID(value.GUID); if (value.APM.FirstOccurence.ContainsKey(payload)) { texture.LoadPayload(IOHelper.OpenFile(value.APM.FirstOccurence[payload])); } else { return(null); } } Stream ms = texture.SaveToDDS(); CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded | CoInit.SpeedOverMemory); byte[] data = new byte[ms.Length]; ms.Read(data, 0, data.Length); ScratchImage scratch = null; try { unsafe { fixed(byte *dataPin = data) { scratch = TexHelper.Instance.LoadFromDDSMemory((IntPtr)dataPin, data.Length, DDS_FLAGS.NONE); TexMetadata info = scratch.GetMetadata(); if (TexHelper.Instance.IsCompressed(info.Format)) { ScratchImage temp = scratch.Decompress(frame, DXGI_FORMAT.UNKNOWN); scratch.Dispose(); scratch = temp; } info = scratch.GetMetadata(); if (info.Format != targetFormat) { ScratchImage temp = scratch.Convert(targetFormat, TEX_FILTER_FLAGS.DEFAULT, 0.5f); scratch.Dispose(); scratch = temp; } UnmanagedMemoryStream stream = null; if (imageFormat == ImageFormat.TGA) { stream = scratch.SaveToTGAMemory(frame < 0 ? 0 : frame); } else { WICCodecs codec = WICCodecs.PNG; bool isMultiframe = false; switch (imageFormat) { case ImageFormat.BMP: codec = WICCodecs.BMP; break; case ImageFormat.GIF: codec = WICCodecs.GIF; isMultiframe = true; break; case ImageFormat.JPEG: codec = WICCodecs.JPEG; break; case ImageFormat.PNG: codec = WICCodecs.PNG; break; case ImageFormat.TIF: codec = WICCodecs.TIFF; isMultiframe = true; break; } if (frame < 0) { if (!isMultiframe) { frame = 0; } else { stream = scratch.SaveToWICMemory(0, info.ArraySize, WIC_FLAGS.ALL_FRAMES, TexHelper.Instance.GetWICCodec(codec)); } } if (frame >= 0) { stream = scratch.SaveToWICMemory(frame, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(codec)); } byte[] tex = new byte[stream.Length]; stream.Read(tex, 0, tex.Length); scratch.Dispose(); return(tex); } } } } catch { if (scratch != null && scratch.IsDisposed == false) { scratch?.Dispose(); } } } catch { } return(null); }
/// <summary> /// Generates the mip maps. /// </summary> /// <param name="image">The image.</param> /// <param name="libraryData">The library data.</param> /// <param name="request">The request.</param> /// <exception cref="TexLibraryException"> /// Not implemented ! /// or /// Mipmaps generation failed /// </exception> private void GenerateMipMaps(TexImage image, DxtTextureLibraryData libraryData, MipMapsGenerationRequest request) { Log.Debug("Generating Mipmaps ... "); var filter = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT; switch (request.Filter) { case Filter.MipMapGeneration.Nearest: filter |= TEX_FILTER_FLAGS.TEX_FILTER_POINT; break; case Filter.MipMapGeneration.Linear: filter |= TEX_FILTER_FLAGS.TEX_FILTER_LINEAR; break; case Filter.MipMapGeneration.Cubic: filter |= TEX_FILTER_FLAGS.TEX_FILTER_CUBIC; break; case Filter.MipMapGeneration.Box: // Box filter is supported only for power of two textures filter |= image.IsPowerOfTwo() ? TEX_FILTER_FLAGS.TEX_FILTER_FANT : TEX_FILTER_FLAGS.TEX_FILTER_LINEAR; break; default: filter |= TEX_FILTER_FLAGS.TEX_FILTER_FANT; break; } // Don't use WIC if we have a Float texture as mipmaps are clamped to [0, 1] // TODO: Report bug to DirectXTex var isPowerOfTwoAndFloat = image.IsPowerOfTwo() && (image.Format == PixelFormat.R16G16_Float || image.Format == PixelFormat.R16G16B16A16_Float); if (isPowerOfTwoAndFloat) { filter = TEX_FILTER_FLAGS.TEX_FILTER_FORCE_NON_WIC; } HRESULT hr; var scratchImage = new ScratchImage(); if (libraryData.Metadata.dimension == TEX_DIMENSION.TEX_DIMENSION_TEXTURE3D) { Log.Info("Only the box and nearest(point) filters are supported for generating Mipmaps with 3D texture."); if ((filter & TEX_FILTER_FLAGS.TEX_FILTER_FANT) == 0 && (filter & TEX_FILTER_FLAGS.TEX_FILTER_POINT) == 0) { filter = (TEX_FILTER_FLAGS)((int)filter & 0xf00000); filter |= TEX_FILTER_FLAGS.TEX_FILTER_FANT; } hr = Utilities.GenerateMipMaps3D(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, filter, 0, scratchImage); } else { hr = Utilities.GenerateMipMaps(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, filter, 0, scratchImage); } if (hr != HRESULT.S_OK) { Log.Error("Mipmaps generation failed: " + hr); throw new TextureToolsException("Mipmaps generation failed: " + hr); } // Freeing Memory if (image.DisposingLibrary != null) { image.DisposingLibrary.Dispose(image); } libraryData.Image = scratchImage; libraryData.Metadata = libraryData.Image.metadata; libraryData.DxtImages = libraryData.Image.GetImages(); image.DisposingLibrary = this; UpdateImage(image, libraryData); }
private async System.Threading.Tasks.Task <bool> CompareImagesAsync(ScratchImage dds, ScratchImage png) { Guid codec = DirectXTexNet.TexHelper.Instance.GetWICCodec(WICCodecs.PNG); TexMetadata metadata = dds.GetMetadata(); UnmanagedMemoryStream ddsStream; if (IsCompressed(metadata.Format)) { using (ScratchImage decompressed = dds.Decompress(DXGI_FORMAT.UNKNOWN)) { ddsStream = decompressed.SaveToWICMemory(0, WIC_FLAGS.NONE, codec); } } else { ddsStream = dds.SaveToWICMemory(0, WIC_FLAGS.NONE, codec); } UnmanagedMemoryStream pngStream = png.SaveToWICMemory(0, WIC_FLAGS.NONE, codec); var scompare = new StreamCompare(); bool result = await scompare.AreEqualAsync(ddsStream, pngStream); ddsStream.Dispose(); pngStream.Dispose(); return(result); }
/* Update file preview */ private void UpdateSelectedFilePreview() { //First, reset the GUI groupBox1.Visible = false; filePreviewImage.BackgroundImage = null; fileNameInfo.Text = ""; fileSizeInfo.Text = ""; fileTypeInfo.Text = ""; exportFile.Enabled = false; importFile.Enabled = false; removeFile.Enabled = false; addFile.Enabled = true; //Eventually move this to only be enabled on directory selection //Exit early if nothing selected if (FileTree.SelectedNode == null) { return; } //Handle file selection if (((TreeItem)FileTree.SelectedNode.Tag).Item_Type == TreeItemType.EXPORTABLE_FILE) { string FileName = ((TreeItem)FileTree.SelectedNode.Tag).String_Value; //Populate filename/type info fileNameInfo.Text = Path.GetFileName(FileName); fileTypeInfo.Text = GetFileTypeDescription(Path.GetExtension(FileName)); //Populate file size info int FileSize = -1; foreach (PAK thisPAK in AlienPAKs) { if (FileSize == -1) { FileSize = thisPAK.GetFileSize(FileName); } } if (FileSize == -1) { return; } fileSizeInfo.Text = FileSize.ToString() + " bytes"; //Show file preview if selected an image if (Path.GetExtension(FileName).ToUpper() == ".DDS") { try { byte[] ImageFile = GetFileAsBytes(FileName); //Using the DDS, try and convert it to Bitmap and display it using (ScratchImage img = TexHelper.Instance.LoadFromDDSMemory(Marshal.UnsafeAddrOfPinnedArrayElement(ImageFile, 0), ImageFile.Length, DDS_FLAGS.NONE)) { ScratchImage imgDecom = img.Decompress(DXGI_FORMAT.UNKNOWN); UnmanagedMemoryStream imgJpg = imgDecom.SaveToWICMemory(0, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(WICCodecs.PNG)); ResizeImagePreview((Bitmap)System.Drawing.Image.FromStream(imgJpg)); } } catch (Exception e) { //MessageBox.Show(e.ToString()); if (File.Exists("temp.dds")) { File.Delete("temp.dds"); } } } groupBox1.Visible = (filePreviewImage.BackgroundImage != null); //Enable buttons exportFile.Enabled = true; importFile.Enabled = true; removeFile.Enabled = true; } }
private void btnAddTexture_Click(object sender, EventArgs e) { if (textureTypeDropdown.SelectedIndex < 0) { //MessageBox.Show("Please select a texture type"); buildStatusLbl.Text = "Please select a texture type!"; return; } string textureType = textureTypeDropdown.SelectedItem.ToString(); openFileDialog1.Filter = "Image Files(*.PNG;*.DDS)|*.PNG;*.DDS|All files (*.*)|*.*"; openFileDialog1.Title = "Add a texture"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if (string.IsNullOrEmpty(openFileDialog1.FileNames[0])) { return; } DisableButtons(true); ScratchImage image; if (Path.GetExtension(openFileDialog1.FileNames[0]).ToUpper() == ".DDS") { image = TexHelper.Instance.LoadFromDDSFile(openFileDialog1.FileNames[0], DDS_FLAGS.NONE); } else { image = TexHelper.Instance.LoadFromWICFile(openFileDialog1.FileNames[0], WIC_FLAGS.NONE); } ScratchImage finalImage = image; var metadata = image.GetMetadata(); if (TexHelper.Instance.IsCompressed(metadata.Format)) { Console.WriteLine("Decompressing..."); buildStatusLbl.Text = "Decompressing..."; finalImage = finalImage.Decompress(DXGI_FORMAT.UNKNOWN); } if (finalImage.GetImageCount() < 11) { Console.WriteLine("GenerateMipMaps..."); buildStatusLbl.Text = "GenerateMipMaps..."; finalImage = finalImage.GenerateMipMaps(TEX_FILTER_FLAGS.DEFAULT, 11); } if (useGPUChk.Checked) { Console.WriteLine("Compressing with GPU..."); buildStatusLbl.Text = "Compressing with GPU..."; var device = new Device(DriverType.Hardware, DeviceCreationFlags.None); var context = device.ImmediateContext; finalImage = finalImage.Compress(device.NativePointer, GetRequiredFormat(textureType), TEX_COMPRESS_FLAGS.PARALLEL, 0.5f); Console.WriteLine("Complete."); } else { Console.WriteLine("Compressing with CPU, this could take a while"); buildStatusLbl.Text = "Compressing with CPU, this could take a while..."; finalImage = finalImage.Compress(GetRequiredFormat(textureType), TEX_COMPRESS_FLAGS.PARALLEL, 0.5f); Console.WriteLine("Complete."); } metadata = finalImage.GetMetadata(); TextureItem newItem = new TextureItem(); var stream = finalImage.SaveToDDSMemory(DDS_FLAGS.NONE); newItem.data = ReadFully(stream); newItem.type = textureType; textureItems.Add(newItem); UpdateList(); buildStatusLbl.Text = "Press Save to save file."; DisableButtons(false); } }
/// <summary> /// Generates the mip maps. /// </summary> /// <param name="image">The image.</param> /// <param name="libraryData">The library data.</param> /// <param name="request">The request.</param> /// <exception cref="TexLibraryException"> /// Not implemented ! /// or /// Mipmaps generation failed /// </exception> private void GenerateMipMaps(TexImage image, DxtTextureLibraryData libraryData, MipMapsGenerationRequest request) { Log.Info("Generating Mipmaps ... "); var filter = TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT; switch (request.Filter) { case Filter.MipMapGeneration.Nearest: filter |= TEX_FILTER_FLAGS.TEX_FILTER_POINT; break; case Filter.MipMapGeneration.Linear: filter |= TEX_FILTER_FLAGS.TEX_FILTER_LINEAR; break; case Filter.MipMapGeneration.Cubic: filter |= TEX_FILTER_FLAGS.TEX_FILTER_CUBIC; break; case Filter.MipMapGeneration.Box: filter |= TEX_FILTER_FLAGS.TEX_FILTER_FANT; break; default: filter |= TEX_FILTER_FLAGS.TEX_FILTER_FANT; break; } HRESULT hr; var scratchImage = new ScratchImage(); if (libraryData.Metadata.dimension == TEX_DIMENSION.TEX_DIMENSION_TEXTURE3D) { Log.Info("Only the box and nearest(point) filters are supported for generating Mipmaps with 3D texture."); if ((filter & TEX_FILTER_FLAGS.TEX_FILTER_FANT) == 0 && (filter & TEX_FILTER_FLAGS.TEX_FILTER_POINT) == 0) { filter = (TEX_FILTER_FLAGS)((int)filter & 0xf00000); filter |= TEX_FILTER_FLAGS.TEX_FILTER_FANT; } hr = Utilities.GenerateMipMaps3D(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, filter, 0, scratchImage); } else { hr = Utilities.GenerateMipMaps(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, filter, 0, scratchImage); } if (hr != HRESULT.S_OK) { Log.Error("Mipmaps generation failed: " + hr); throw new TextureToolsException("Mipmaps generation failed: " + hr); } // Freeing Memory if (image.DisposingLibrary != null) { image.DisposingLibrary.Dispose(image); } libraryData.Image = scratchImage; libraryData.Metadata = libraryData.Image.metadata; libraryData.DxtImages = libraryData.Image.GetImages(); image.DisposingLibrary = this; UpdateImage(image, libraryData); }
/// <summary> /// Splits the image by all channels /// </summary> private void SplitRGBA(string imagePath, string extension, ScratchImage.DXGIFormat outFormat, string outputPath = null) { using (var inputImage = new ScratchImage(imagePath)) { // Force the image to a standard format inputImage.ConvertImage(ScratchImage.DXGIFormat.R8G8B8A8UNORM); var inputPixels = inputImage.GetPixels(); var rPixels = new byte[inputPixels.Length]; var gPixels = new byte[inputPixels.Length]; var bPixels = new byte[inputPixels.Length]; var aPixels = new byte[inputPixels.Length]; for (int i = 0; i < inputPixels.Length; i += 4) { // Copy Red rPixels[i + 0] = inputPixels[i]; rPixels[i + 1] = inputPixels[i]; rPixels[i + 2] = inputPixels[i]; rPixels[i + 3] = 0xFF; // Copy Blue bPixels[i + 0] = inputPixels[i + 1]; bPixels[i + 1] = inputPixels[i + 1]; bPixels[i + 2] = inputPixels[i + 1]; bPixels[i + 3] = 0xFF; // Copy Green gPixels[i + 0] = inputPixels[i + 2]; gPixels[i + 1] = inputPixels[i + 2]; gPixels[i + 2] = inputPixels[i + 2]; gPixels[i + 3] = 0xFF; // Copy Alpha aPixels[i + 0] = inputPixels[i + 3]; aPixels[i + 1] = inputPixels[i + 3]; aPixels[i + 2] = inputPixels[i + 3]; aPixels[i + 3] = 0xFF; } if (outputPath == null) { outputPath = Path.Combine( Path.GetDirectoryName(imagePath), Path.GetFileNameWithoutExtension(imagePath).Replace("-", "_").Replace("~", "").Replace("&", "_")); } using (var r = new ScratchImage(inputImage.Metadata, rPixels)) using (var g = new ScratchImage(inputImage.Metadata, bPixels)) using (var b = new ScratchImage(inputImage.Metadata, gPixels)) using (var a = new ScratchImage(inputImage.Metadata, aPixels)) { if (extension == ".dds") { r.ConvertImage(outFormat); g.ConvertImage(outFormat); b.ConvertImage(outFormat); a.ConvertImage(outFormat); } r.Save(outputPath + "_r" + extension); g.Save(outputPath + "_g" + extension); b.Save(outputPath + "_b" + extension); a.Save(outputPath + "_a" + extension); } } }
public static unsafe byte[] CompressBlock(Byte[] data, int width, int height, DDS.DXGI_FORMAT format, bool multiThread, float AlphaRef = 0.5f, STCompressionMode CompressionMode = STCompressionMode.Normal) { long inputRowPitch = width * 4; long inputSlicePitch = width * height * 4; if (data.Length == inputSlicePitch) { byte *buf; buf = (byte *)Marshal.AllocHGlobal((int)inputSlicePitch); Marshal.Copy(data, 0, (IntPtr)buf, (int)inputSlicePitch); DirectXTexNet.Image inputImage = new DirectXTexNet.Image( width, height, DXGI_FORMAT.R8G8B8A8_UNORM, inputRowPitch, inputSlicePitch, (IntPtr)buf, null); TexMetadata texMetadata = new TexMetadata(width, height, 1, 1, 1, 0, 0, DXGI_FORMAT.R8G8B8A8_UNORM, TEX_DIMENSION.TEXTURE2D); ScratchImage scratchImage = TexHelper.Instance.InitializeTemporary( new DirectXTexNet.Image[] { inputImage }, texMetadata, null); var compFlags = TEX_COMPRESS_FLAGS.DEFAULT; if (multiThread) { compFlags |= TEX_COMPRESS_FLAGS.PARALLEL; } if (format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS) { if (CompressionMode == STCompressionMode.Fast) { compFlags |= TEX_COMPRESS_FLAGS.BC7_QUICK; } } if (format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB || format == DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB) { compFlags |= TEX_COMPRESS_FLAGS.SRGB; } using (var comp = scratchImage.Compress((DXGI_FORMAT)format, compFlags, 0.5f)) { long outRowPitch; long outSlicePitch; TexHelper.Instance.ComputePitch((DXGI_FORMAT)format, width, height, out outRowPitch, out outSlicePitch, CP_FLAGS.NONE); byte[] result = new byte[outSlicePitch]; Marshal.Copy(comp.GetImage(0).Pixels, result, 0, result.Length); inputImage = null; scratchImage.Dispose(); return(result); } } return(null); }
public static unsafe byte[] ConvertDDS(Stream ddsSteam, DXGI_FORMAT targetFormat, WICCodecs codec, int frame) { try { CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded | CoInit.SpeedOverMemory); byte[] data = new byte[ddsSteam.Length]; ddsSteam.Read(data, 0, data.Length); ScratchImage scratch = null; try { fixed(byte *dataPin = data) { scratch = TexHelper.Instance.LoadFromDDSMemory((IntPtr)dataPin, data.Length, DDS_FLAGS.NONE); TexMetadata info = scratch.GetMetadata(); if (TexHelper.Instance.IsCompressed(info.Format)) { ScratchImage temp = scratch.Decompress(DXGI_FORMAT.UNKNOWN); scratch.Dispose(); scratch = temp; info = scratch.GetMetadata(); } if (info.Format != targetFormat) { ScratchImage temp = scratch.Convert(targetFormat, TEX_FILTER_FLAGS.DEFAULT, 0.5f); scratch.Dispose(); scratch = temp; } UnmanagedMemoryStream stream = null; var isMultiFrame = codec == WICCodecs.GIF || codec == WICCodecs.TIFF; if (info.ArraySize == 1 || !isMultiFrame) { stream = scratch.SaveToWICMemory(frame, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(codec)); } else { stream = scratch.SaveToWICMemory(0, info.ArraySize, WIC_FLAGS.ALL_FRAMES, TexHelper.Instance.GetWICCodec(codec)); } if (stream == null) { return(null); } byte[] tex = new byte[stream.Length]; stream.Read(tex, 0, tex.Length); scratch.Dispose(); return(tex); } } catch { if (scratch != null && scratch.IsDisposed == false) { scratch.Dispose(); } } } catch { // ignored } return(null); }
private static void Main() { var form = new RenderForm("SharpDX - MiniCubeTexture Direct3D11 Sample"); // SwapChain description var desc = new SwapChainDescription() { BufferCount = 1, ModeDescription = new ModeDescription(form.ClientSize.Width, form.ClientSize.Height, new Rational(60, 1), Format.R8G8B8A8_UNorm), IsWindowed = true, OutputHandle = form.Handle, SampleDescription = new SampleDescription(1, 0), SwapEffect = SwapEffect.Discard, Usage = Usage.RenderTargetOutput }; // Create Device and SwapChain Device device; SwapChain swapChain; Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, desc, out device, out swapChain); var context = device.ImmediateContext; // Ignore all windows events var factory = swapChain.GetParent <Factory>(); factory.MakeWindowAssociation(form.Handle, WindowAssociationFlags.IgnoreAll); // New RenderTargetView from the backbuffer var backBuffer = Texture2D.FromSwapChain <Texture2D>(swapChain, 0); var renderView = new RenderTargetView(device, backBuffer); // Compile Vertex and Pixel shaders var vertexShaderByteCode = File.ReadAllBytes("MiniCubeTexture_vs.fxo"); var vertexShader = new VertexShader(device, vertexShaderByteCode); var pixelShaderByteCode = File.ReadAllBytes("MiniCubeTexture_ps.fxo"); var pixelShader = new PixelShader(device, pixelShaderByteCode); // Layout from VertexShader input signature var layout = new InputLayout(device, vertexShaderByteCode, new[] { new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0), new InputElement("TEXCOORD", 0, Format.R32G32_Float, 16, 0) }); // Instantiate Vertex buiffer from vertex data var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[] { // 3D coordinates UV Texture coordinates -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Front -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, // BACK 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Top -1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, // Bottom 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, // Left -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, // Right 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, }); // Create Constant Buffer var contantBuffer = new Buffer(device, Utilities.SizeOf <Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0); // Create Depth Buffer & View var depthBuffer = new Texture2D(device, new Texture2DDescription() { Format = Format.D32_Float_S8X24_UInt, ArraySize = 1, MipLevels = 1, Width = form.ClientSize.Width, Height = form.ClientSize.Height, SampleDescription = new SampleDescription(1, 0), Usage = ResourceUsage.Default, BindFlags = BindFlags.DepthStencil, CpuAccessFlags = CpuAccessFlags.None, OptionFlags = ResourceOptionFlags.None }); var depthView = new DepthStencilView(device, depthBuffer); // Load texture and create sampler TexMetadata metadata; var image = ScratchImage.LoadFromWICFile("GeneticaMortarlessBlocks.jpg", WICFlags.None, out metadata); var texture = image.CreateTexture(device); var textureView = new ShaderResourceView(device, texture); var sampler = new SamplerState(device, new SamplerStateDescription() { Filter = Filter.MinMagMipLinear, AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, BorderColor = Color.Black, ComparisonFunction = Comparison.Never, MaximumAnisotropy = 16, MipLodBias = 0, MinimumLod = 0, MaximumLod = 16, }); // Prepare All the stages context.InputAssembler.InputLayout = layout; context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf <Vector4>() + Utilities.SizeOf <Vector2>(), 0)); context.VertexShader.SetConstantBuffer(0, contantBuffer); context.VertexShader.Set(vertexShader); context.Rasterizer.SetViewport(new Viewport(0, 0, form.ClientSize.Width, form.ClientSize.Height, 0.0f, 1.0f)); context.PixelShader.Set(pixelShader); context.PixelShader.SetSampler(0, sampler); context.PixelShader.SetShaderResource(0, textureView); context.OutputMerger.SetTargets(depthView, renderView); // Prepare matrices var view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY); var proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, form.ClientSize.Width / (float)form.ClientSize.Height, 0.1f, 100.0f); var viewProj = Matrix.Multiply(view, proj); // Use clock var clock = new Stopwatch(); clock.Start(); // Main loop RenderLoop.Run(form, () => { var time = clock.ElapsedMilliseconds / 1000.0f; // Clear views context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0); context.ClearRenderTargetView(renderView, Color.Black); // Update WorldViewProj Matrix var worldViewProj = Matrix.RotationX(time) * Matrix.RotationY(time * 2) * Matrix.RotationZ(time * .7f) * viewProj; worldViewProj.Transpose(); context.UpdateSubresource(ref worldViewProj, contantBuffer); // Draw the cube context.Draw(36, 0); // Present! swapChain.Present(0, PresentFlags.None); }); // Release all resources vertexShader.Dispose(); pixelShader.Dispose(); vertices.Dispose(); layout.Dispose(); renderView.Dispose(); backBuffer.Dispose(); context.ClearState(); context.Flush(); device.Dispose(); context.Dispose(); swapChain.Dispose(); factory.Dispose(); }
/// <summary> /// Matches a given DDS file on the disk to a D3DTX object. /// </summary> /// <param name="ddsPath"></param> /// <param name="d3dtx"></param> /// <param name="options"></param> public void Match_DDS_With_D3DTX(string ddsPath, D3DTX_Master d3dtx, DDS_Matching_Options options) { //load in the DDS image using DirectXTexNet ScratchImage scratchImage = TexHelper.Instance.LoadFromDDSFile(ddsPath, DDS_FLAGS.NONE); //create our main variables that will be used when doing conversion operations int d3dtx_width = 0; int d3dtx_height = 0; int d3dtx_mipAmount = 0; T3SurfaceFormat d3dtx_format = T3SurfaceFormat.eSurface_DXT1; T3SurfaceGamma d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //assign the values depending on which version is active if (d3dtx.d3dtx9 != null) { d3dtx_width = (int)d3dtx.d3dtx9.mWidth; d3dtx_height = (int)d3dtx.d3dtx9.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx9.mNumMipLevels; d3dtx_format = d3dtx.d3dtx9.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx9.mSurfaceGamma; } else if (d3dtx.d3dtx8 != null) { d3dtx_width = (int)d3dtx.d3dtx8.mWidth; d3dtx_height = (int)d3dtx.d3dtx8.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx8.mNumMipLevels; d3dtx_format = d3dtx.d3dtx8.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx8.mSurfaceGamma; } else if (d3dtx.d3dtx7 != null) { d3dtx_width = (int)d3dtx.d3dtx7.mWidth; d3dtx_height = (int)d3dtx.d3dtx7.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx7.mNumMipLevels; d3dtx_format = d3dtx.d3dtx7.mSurfaceFormat; d3dtx_gamma = d3dtx.d3dtx7.mSurfaceGamma; } else if (d3dtx.d3dtx6 != null) { d3dtx_width = (int)d3dtx.d3dtx6.mWidth; d3dtx_height = (int)d3dtx.d3dtx6.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx6.mNumMipLevels; d3dtx_format = d3dtx.d3dtx6.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } else if (d3dtx.d3dtx5 != null) { d3dtx_width = (int)d3dtx.d3dtx5.mWidth; d3dtx_height = (int)d3dtx.d3dtx5.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx5.mNumMipLevels; d3dtx_format = d3dtx.d3dtx5.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } else if (d3dtx.d3dtx4 != null) { d3dtx_width = (int)d3dtx.d3dtx4.mWidth; d3dtx_height = (int)d3dtx.d3dtx4.mHeight; d3dtx_mipAmount = (int)d3dtx.d3dtx4.mNumMipLevels; d3dtx_format = d3dtx.d3dtx4.mSurfaceFormat; d3dtx_gamma = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default } //-------------------------------------- CONVERSION START -------------------------------------- //change the compression if needed if (options.MatchCompression) { DXGI_FORMAT dxgi_format = DDS_Functions.GetSurfaceFormatAsDXGI(d3dtx_format, d3dtx_gamma); scratchImage.Convert(dxgi_format, TEX_FILTER_FLAGS.DITHER, 0.0f); } //rescale the image to match if needed if (options.MatchResolution) { scratchImage.Resize(d3dtx_width, d3dtx_height, TEX_FILTER_FLAGS.CUBIC); } //generate mip maps if needed if (options.GenerateMipMaps) { if (options.MatchMipMapCount) { scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, d3dtx_mipAmount, false); } else { scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, 0, false); } } //resave the newly modified DDS scratchImage.SaveToDDSFile(DDS_FLAGS.NONE, ddsPath); }
/* Export the selected PAK entry as a standalone file */ private void ExportSelectedFile() { if (FileTree.SelectedNode == null || ((TreeItem)FileTree.SelectedNode.Tag).Item_Type != TreeItemType.EXPORTABLE_FILE) { MessageBox.Show("Please select a file from the list.", "No file selected.", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } //If export file is DDS, check first to see if we can export as WIC format string filter = "Exported File|*" + Path.GetExtension(FileTree.SelectedNode.Text); byte[] ImageFile = new byte[] { }; if (Path.GetExtension(FileTree.SelectedNode.Text).ToUpper() == ".DDS") { ImageFile = GetFileAsBytes(((TreeItem)FileTree.SelectedNode.Tag).String_Value); try { TexHelper.Instance.LoadFromDDSMemory(Marshal.UnsafeAddrOfPinnedArrayElement(ImageFile, 0), ImageFile.Length, DDS_FLAGS.NONE); filter = "PNG Image|*.png|DDS Image|*.dds"; //Can export as WIC } catch { ImageFile = new byte[] { }; } } //Remove extension from output filename string filename = Path.GetFileName(FileTree.SelectedNode.Text); while (Path.GetExtension(filename).Length != 0) { filename = filename.Substring(0, filename.Length - Path.GetExtension(filename).Length); } //Let the user decide where to save, then save SaveFileDialog FilePicker = new SaveFileDialog(); FilePicker.Filter = filter; FilePicker.FileName = filename; if (FilePicker.ShowDialog() == DialogResult.OK) { Cursor.Current = Cursors.WaitCursor; //Special export for DDS conversion if (ImageFile.Length > 0 && FilePicker.FilterIndex == 1) //Index 1 == PNG, if ImageFile hasn't been cleared (we can export as WIC) { try { ScratchImage img = TexHelper.Instance.LoadFromDDSMemory(Marshal.UnsafeAddrOfPinnedArrayElement(ImageFile, 0), ImageFile.Length, DDS_FLAGS.NONE); ScratchImage imgDecom = img.Decompress(DXGI_FORMAT.UNKNOWN); imgDecom.SaveToWICFile(0, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(WICCodecs.PNG), FilePicker.FileName); MessageBox.Show(AlienErrors.ErrorMessageBody(PAKReturnType.SUCCESS), AlienErrors.ErrorMessageTitle(PAKReturnType.SUCCESS), MessageBoxButtons.OK, MessageBoxIcon.Information); } catch { MessageBox.Show("Failed to export as PNG!\nPlease try again as DDS.", AlienErrors.ErrorMessageTitle(PAKReturnType.FAIL_UNKNOWN), MessageBoxButtons.OK, MessageBoxIcon.Information); } } //Regular export else { PAKReturnType ResponseCode = PAKReturnType.FAIL_UNKNOWN; foreach (PAK thisPAK in AlienPAKs) { ResponseCode = thisPAK.ExportFile(((TreeItem)FileTree.SelectedNode.Tag).String_Value, FilePicker.FileName); if (ResponseCode == PAKReturnType.SUCCESS || ResponseCode == PAKReturnType.SUCCESS_WITH_WARNINGS) { break; } } MessageBox.Show(AlienErrors.ErrorMessageBody(ResponseCode), AlienErrors.ErrorMessageTitle(ResponseCode), MessageBoxButtons.OK, MessageBoxIcon.Information); } Cursor.Current = Cursors.Default; } }