public static GLTexture2DArray FromRawData(int width, int height, TexFormat format, byte[] data)
        {
            GLTexture2DArray texture = new GLTexture2DArray();

            texture.Width = width; texture.Height = height;
            texture.LoadImage(width, height, format, data);
            return(texture);
        }
        public static GLTexture2DArray FromBitmap(Bitmap image)
        {
            GLTexture2DArray texture = new GLTexture2DArray();

            texture.Width = image.Width; texture.Height = image.Height;
            texture.LoadImage(image);
            return(texture);
        }
        public static GLTexture2DArray FromGeneric(STGenericTexture texture, ImageParameters parameters)
        {
            GLTexture2DArray glTexture = new GLTexture2DArray();

            glTexture.Width  = (int)texture.Width;
            glTexture.Height = (int)texture.Height;
            glTexture.LoadImage(texture, parameters);
            return(glTexture);
        }
        public static GLTexture2DArray FromDDS(DDS dds)
        {
            GLTexture2DArray texture = new GLTexture2DArray();

            texture.Width = (int)dds.Width; texture.Height = (int)dds.Height;
            texture.Bind();

            GL.TexParameter(texture.Target, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
            GL.TexParameter(texture.Target, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            GL.TexParameter(texture.Target, TextureParameterName.TextureBaseLevel, 0);
            GL.TexParameter(texture.Target, TextureParameterName.TextureMaxLevel, 13);
            GL.TexParameter(texture.Target, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge);
            GL.TexParameter(texture.Target, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);
            GL.TexParameter(texture.Target, TextureParameterName.TextureWrapR, (int)TextureWrapMode.ClampToEdge);

            InternalFormat format = InternalFormat.Rgba8;

            for (int j = 0; j < dds.MipCount; j++)
            {
                int mipWidth  = CalculateMipDimension(texture.Width, j);
                int mipHeight = CalculateMipDimension(texture.Height, j);
                int imageSize = GLFormatHelper.CalculateImageSize(mipWidth, mipHeight, format) * (int)dds.ArrayCount;

                List <byte[]> levels = new List <byte[]>();
                for (int i = 0; i < dds.ArrayCount; i++)
                {
                    var data = dds.GetDecodedSurface(i, j);
                    if (i == 0 || i == 1)
                    {
                        data = FlipHorizontal(mipWidth, mipHeight, data);
                    }

                    levels.Add(data);
                }

                var surface = ByteUtils.CombineArray(levels.ToArray());
                if (format == InternalFormat.Rgba8)
                {
                    GL.TexImage3D(TextureTarget.Texture2DArray, j,
                                  PixelInternalFormat.Rgba,
                                  mipWidth, mipHeight, (int)dds.ArrayCount, 0, PixelFormat.Bgra, PixelType.UnsignedByte,
                                  surface);
                }
                else
                {
                    GL.CompressedTexImage3D(TextureTarget.Texture2DArray, j,
                                            format,
                                            mipWidth, mipHeight, (int)dds.ArrayCount,
                                            0, imageSize, surface);
                }
            }

            texture.Unbind();
            return(texture);
        }
        public static GLTexture FromGenericTexture(STGenericTexture texture, ImageParameters parameters = null)
        {
            if (parameters == null)
            {
                parameters = new ImageParameters();
            }

            switch (texture.SurfaceType)
            {
            case STSurfaceType.Texture2D_Array:
                return(GLTexture2DArray.FromGeneric(texture, parameters));

            case STSurfaceType.Texture3D:
                return(GLTexture3D.FromGeneric(texture, parameters));

            case STSurfaceType.TextureCube:
                return(GLTextureCube.FromGeneric(texture, parameters));

            default:
                return(GLTexture2D.FromGeneric(texture, parameters));
            }
        }
        public static GLTexture2DArray CreateUncompressedTexture(int width, int height, int arrayCount, int mipCount,
                                                                 PixelInternalFormat pixelInternalFormat = PixelInternalFormat.Rgba8,
                                                                 PixelFormat pixelFormat = PixelFormat.Rgba,
                                                                 PixelType pixelType     = PixelType.UnsignedByte)
        {
            GLTexture2DArray texture = new GLTexture2DArray();

            texture.PixelFormat         = pixelFormat;
            texture.PixelType           = pixelType;
            texture.PixelInternalFormat = pixelInternalFormat;
            texture.Width      = width; texture.Height = height;
            texture.Target     = TextureTarget.Texture2DArray;
            texture.MinFilter  = TextureMinFilter.LinearMipmapLinear;
            texture.MagFilter  = TextureMagFilter.Linear;
            texture.MipCount   = mipCount;
            texture.ArrayCount = arrayCount;
            texture.Bind();

            //Allocate mip data
            if (texture.MipCount > 1)
            {
                texture.GenerateMipmaps();
            }

            for (int mip = 0; mip < texture.MipCount; mip++)
            {
                int mipWidth  = (int)(texture.Width * Math.Pow(0.5, mip));
                int mipHeight = (int)(texture.Height * Math.Pow(0.5, mip));

                GL.TexImage3D(texture.Target, 0, texture.PixelInternalFormat,
                              mipWidth, mipHeight, texture.ArrayCount, mip,
                              texture.PixelFormat, texture.PixelType, IntPtr.Zero);
            }

            texture.UpdateParameters();
            texture.Unbind();
            return(texture);
        }