Пример #1
0
        /// <summary>
        /// Creates a cached texture for the specifed texture, using the specified path
        /// as a lookup key.
        /// </summary>
        public int CreateCachedTexture(BLP texture, string texturePath, TextureWrapMode textureWrapMode = TextureWrapMode.Repeat)
        {
            if (texture == null)
            {
                throw new ArgumentNullException(nameof(texture));
            }

            int textureID = GL.GenTexture();

            if (texture.GetCompressionType() == TextureCompressionType.DXTC)
            {
                try
                {
                    LoadDXTTexture(textureID, texture);
                }
                catch (GraphicsErrorException gex)
                {
                    Log.Warn($"GraphicsErrorException in CreateCachedTexture (failed to create DXT texture): {gex.Message}\n" +
                             "The texture will be loaded as a bitmap instead.");
                }
                finally
                {
                    // Load a fallback bitmap instead
                    using (Bitmap mipZero = texture.GetMipMap(0))
                    {
                        LoadBitmapTexture(textureID, mipZero);
                    }
                }
            }
            else
            {
                using (Bitmap mipZero = texture.GetMipMap(0))
                {
                    LoadBitmapTexture(textureID, mipZero);
                }
            }

            // Use linear mipmapped filtering
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);

            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)textureWrapMode);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)textureWrapMode);

            int maximalMipLevel = texture.GetMipMapCount() == 0 ? 0 : texture.GetMipMapCount() - 1;

            GL.TexParameterI(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, ref maximalMipLevel);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);

            this.GLTextureCache.Add(texturePath.ConvertPathSeparatorsToCurrentNativeSeparator().ToUpperInvariant(), textureID);
            return(textureID);
        }
Пример #2
0
        /// <summary>
        /// Loads the specified compressed image (in <see cref="BLP"/> format) into a native OpenGL texture.
        /// </summary>
        /// <param name="textureID">The ID of the texture to load the image into.</param>
        /// <param name="compressedImage">The compressed image to load.</param>
        /// <exception cref="ArgumentException">
        /// Thrown if the image format does not match the pixel format.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Thrown if the input image is null.
        /// </exception>
        private static void LoadDXTTexture(int textureID, BLP compressedImage)
        {
            if (compressedImage == null)
            {
                throw new ArgumentNullException(nameof(compressedImage));
            }

            GL.BindTexture(TextureTarget.Texture2D, textureID);

            // Load the set of raw compressed mipmaps
            for (uint i = 0; i < compressedImage.GetMipMapCount(); ++i)
            {
                byte[]     compressedMipMap = compressedImage.GetRawMipMap(i);
                Resolution mipResolution    = compressedImage.GetMipLevelResolution(i);

                PixelInternalFormat compressionFormat;
                switch (compressedImage.GetPixelFormat())
                {
                case BLPPixelFormat.DXT1:
                {
                    compressionFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                    break;
                }

                case BLPPixelFormat.DXT3:
                {
                    compressionFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                    break;
                }

                case BLPPixelFormat.DXT5:
                {
                    compressionFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                    break;
                }

                default:
                {
                    throw new ArgumentException($"Image format (DXTC) did not match pixel format: {compressedImage.GetPixelFormat()}", nameof(Image));
                }
                }

                // Load the mipmap into the texture
                GL.CompressedTexImage2D(TextureTarget.Texture2D, (int)i,
                                        compressionFormat,
                                        (int)mipResolution.X,
                                        (int)mipResolution.Y,
                                        0,
                                        compressedMipMap.Length,
                                        compressedMipMap);
            }
        }