public void LoadOpenGLTexture(STGenericTexture GenericTexture, int ArrayStartIndex = 0, bool LoadArrayLevels = false)
        {
            if (!Runtime.OpenTKInitialized || GLInitialized || Runtime.UseLegacyGL)
            {
                return;
            }

            width  = (int)GenericTexture.Width;
            height = (int)GenericTexture.Height;

            if (Runtime.DisableLoadingGLHighResTextures)
            {
                if (width >= 3000 || height >= 3000)
                {
                    return;
                }
            }

            if (GenericTexture.ArrayCount == 0)
            {
                GenericTexture.ArrayCount = 1;
            }

            List <STGenericTexture.Surface> Surfaces = new List <STGenericTexture.Surface>();

            if (UseMipmaps && GenericTexture.ArrayCount <= 1)
            {
                //Load surfaces with mip maps
                Surfaces = GenericTexture.GetSurfaces(ArrayStartIndex, false, 6);
            }
            else
            {
                //Only load first mip level. Will be generated after
                for (int i = 0; i < GenericTexture.ArrayCount; i++)
                {
                    if (i >= ArrayStartIndex && i <= ArrayStartIndex + 6) //Only load up to 6 faces
                    {
                        Surfaces.Add(new STGenericTexture.Surface()
                        {
                            mipmaps = new List <byte[]>()
                            {
                                GenericTexture.GetImageData(i, 0)
                            }
                        });
                    }
                }
            }

            if (Surfaces.Count == 0 || Surfaces[0].mipmaps[0].Length == 0)
            {
                return;
            }

            IsCubeMap = Surfaces.Count == 6;
            ImageSize = Surfaces[0].mipmaps[0].Length;

            if (IsCubeMap)
            {
                TextureTarget    = TextureTarget.TextureCubeMap;
                TextureWrapS     = TextureWrapMode.Clamp;
                TextureWrapT     = TextureWrapMode.Clamp;
                TextureWrapR     = TextureWrapMode.Clamp;
                TextureMinFilter = TextureMinFilter.LinearMipmapLinear;
                TextureMagFilter = TextureMagFilter.Linear;
            }

            switch (GenericTexture.Format)
            {
            case TEX_FORMAT.BC1_UNORM:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                break;

            case TEX_FORMAT.BC1_UNORM_SRGB:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt1Ext;
                break;

            case TEX_FORMAT.BC2_UNORM:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                break;

            case TEX_FORMAT.BC2_UNORM_SRGB:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt3Ext;
                break;

            case TEX_FORMAT.BC3_UNORM:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                break;

            case TEX_FORMAT.BC3_UNORM_SRGB:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaS3tcDxt5Ext;
                break;

            case TEX_FORMAT.BC4_UNORM:
            case TEX_FORMAT.BC4_SNORM:
                //Convert to rgb to prevent red output
                //While shaders could prevent this, converting is easier and works fine across all editors
                if (Runtime.UseDirectXTexDecoder)
                {
                    pixelInternalFormat = PixelInternalFormat.Rgba;
                    pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                }
                else
                {
                    pixelInternalFormat = PixelInternalFormat.CompressedRedRgtc1;
                    pixelInternalFormat = PixelInternalFormat.CompressedSignedRedRgtc1;
                }
                break;

            case TEX_FORMAT.BC5_SNORM:
                pixelInternalFormat = PixelInternalFormat.Rgba;
                pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                break;

            case TEX_FORMAT.BC5_UNORM:
                pixelInternalFormat = PixelInternalFormat.CompressedRgRgtc2;
                break;

            case TEX_FORMAT.BC6H_UF16:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcUnsignedFloat;
                break;

            case TEX_FORMAT.BC6H_SF16:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbBptcSignedFloat;
                break;

            case TEX_FORMAT.BC7_UNORM:
                pixelInternalFormat = PixelInternalFormat.CompressedRgbaBptcUnorm;
                break;

            case TEX_FORMAT.BC7_UNORM_SRGB:
                pixelInternalFormat = PixelInternalFormat.CompressedSrgbAlphaBptcUnorm;
                break;

            case TEX_FORMAT.R8G8B8A8_UNORM:
                pixelInternalFormat = PixelInternalFormat.Rgba;
                pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                break;

            case TEX_FORMAT.R8G8B8A8_UNORM_SRGB:
                pixelInternalFormat = PixelInternalFormat.Rgba;
                pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                break;

            default:
                if (Runtime.UseDirectXTexDecoder)
                {
                    pixelInternalFormat = PixelInternalFormat.Rgba;
                    pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;
                }
                break;
            }
            GLInitialized = true;
            for (int i = 0; i < Surfaces.Count; i++)
            {
                for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++)
                {
                    uint width  = Math.Max(1, GenericTexture.Width >> MipLevel);
                    uint height = Math.Max(1, GenericTexture.Height >> MipLevel);

                    Surfaces[i].mipmaps[MipLevel] = DecodeWithoutOpenGLDecoder(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture);
                }
            }

            TexID = GenerateOpenGLTexture(this, Surfaces);

            Surfaces.Clear();
        }
Exemple #2
0
        public void LoadOpenGLTexture(STGenericTexture GenericTexture, int ArrayStartIndex = 0, bool LoadArrayLevels = false)
        {
            if (!Runtime.OpenTKInitialized || GLInitialized || Runtime.UseLegacyGL || IsFailedState)
            {
                return;
            }

            width  = (int)GenericTexture.Width;
            height = (int)GenericTexture.Height;

            if (Runtime.DisableLoadingGLHighResTextures)
            {
                if (width >= 3000 || height >= 3000)
                {
                    return;
                }
            }

            switch (GenericTexture.SurfaceType)
            {
            case STSurfaceType.Texture1D:
                TextureTarget = TextureTarget.Texture1D;
                break;

            case STSurfaceType.Texture2D:
                TextureTarget = TextureTarget.Texture2D;
                break;

            case STSurfaceType.Texture2D_Array:
                TextureTarget = TextureTarget.Texture2DArray;
                break;

            case STSurfaceType.Texture2D_Mulitsample:
                TextureTarget = TextureTarget.Texture2DMultisample;
                break;

            case STSurfaceType.Texture2D_Multisample_Array:
                TextureTarget = TextureTarget.Texture2DMultisampleArray;
                break;

            case STSurfaceType.Texture3D:
                TextureTarget = TextureTarget.Texture3D;
                break;

            case STSurfaceType.TextureCube:
                TextureTarget = TextureTarget.TextureCubeMap;
                break;

            case STSurfaceType.TextureCube_Array:
                TextureTarget = TextureTarget.TextureCubeMapArray;
                break;
            }

            if (GenericTexture.ArrayCount == 0)
            {
                GenericTexture.ArrayCount = 1;
            }

            List <STGenericTexture.Surface> Surfaces = new List <STGenericTexture.Surface>();

            try
            {
                if (UseMipmaps && GenericTexture.ArrayCount <= 1)
                {
                    //Load surfaces with mip maps
                    Surfaces = GenericTexture.GetSurfaces(ArrayStartIndex, false, 6);
                }
                else
                {
                    //Only load first mip level. Will be generated after
                    for (int i = 0; i < GenericTexture.ArrayCount; i++)
                    {
                        if (i >= ArrayStartIndex && i <= ArrayStartIndex + 6) //Only load up to 6 faces
                        {
                            Surfaces.Add(new STGenericTexture.Surface()
                            {
                                mipmaps = new List <byte[]>()
                                {
                                    GenericTexture.GetImageData(i, 0)
                                }
                            });
                        }
                    }
                }

                if (Surfaces.Count == 0 || Surfaces[0].mipmaps[0].Length == 0)
                {
                    return;
                }

                IsCubeMap = Surfaces.Count == 6;
                ImageSize = Surfaces[0].mipmaps[0].Length;

                if (IsCubeMap)
                {
                    TextureTarget = TextureTarget.TextureCubeMap;
                }

                //Force RGBA and use ST for decoding for weird width/heights
                //Open GL decoder has issues with certain width/heights

                Console.WriteLine($"width pow {width} {IsPow2(width)}");
                Console.WriteLine($"height pow {height} {IsPow2(height)}");

                if (!IsPow2(width) || !IsPow2(height))
                {
                    UseOpenGLDecoder = false;
                }

                pixelInternalFormat = PixelInternalFormat.Rgba;
                pixelFormat         = OpenTK.Graphics.OpenGL.PixelFormat.Rgba;

                if (GenericTexture.PlatformSwizzle == PlatformSwizzle.Platform_3DS ||
                    GenericTexture.PlatformSwizzle == PlatformSwizzle.Platform_Gamecube)
                {
                    UseOpenGLDecoder = false;
                    pixelFormat      = OpenTK.Graphics.OpenGL.PixelFormat.Bgra;
                }


                if (UseOpenGLDecoder)
                {
                    SetPixelFormats(GenericTexture.Format);
                }

                GLInitialized = true;
                for (int i = 0; i < Surfaces.Count; i++)
                {
                    for (int MipLevel = 0; MipLevel < Surfaces[i].mipmaps.Count; MipLevel++)
                    {
                        uint width  = Math.Max(1, GenericTexture.Width >> MipLevel);
                        uint height = Math.Max(1, GenericTexture.Height >> MipLevel);

                        Surfaces[i].mipmaps[MipLevel] = DecodeWithoutOpenGLDecoder(Surfaces[i].mipmaps[MipLevel], width, height, GenericTexture);
                    }
                }

                TexID = GenerateOpenGLTexture(this, Surfaces);

                if (IsCubeMap)
                {
                    TextureWrapS     = TextureWrapMode.Clamp;
                    TextureWrapT     = TextureWrapMode.Clamp;
                    TextureWrapR     = TextureWrapMode.Clamp;
                    TextureMinFilter = TextureMinFilter.LinearMipmapLinear;
                    TextureMagFilter = TextureMagFilter.Linear;
                }

                Surfaces.Clear();
            }
            catch
            {
                IsFailedState = true;
                GLInitialized = false;
                return;
            }
        }