Exemplo n.º 1
0
        /// <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);
        }
Exemplo n.º 2
0
        /// <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);
        }