/// <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: // 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); }
/// <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); }