diff --git a/OpenRA.Platforms.Default/OpenGL.cs b/OpenRA.Platforms.Default/OpenGL.cs index a2f351fd6e..58ff9ec72a 100644 --- a/OpenRA.Platforms.Default/OpenGL.cs +++ b/OpenRA.Platforms.Default/OpenGL.cs @@ -297,6 +297,9 @@ namespace OpenRA.Platforms.Default public delegate void DeleteTextures(int n, ref uint textures); public static DeleteTextures glDeleteTextures { get; private set; } + public delegate bool IsTexture(uint texture); + public static IsTexture glIsTexture { get; private set; } + public delegate void BindTexture(int target, uint texture); public static BindTexture glBindTexture { get; private set; } @@ -423,6 +426,7 @@ namespace OpenRA.Platforms.Default glReadPixels = Bind("glReadPixels"); glGenTextures = Bind("glGenTextures"); glDeleteTextures = Bind("glDeleteTextures"); + glIsTexture = Bind("glIsTexture"); glBindTexture = Bind("glBindTexture"); glActiveTexture = Bind("glActiveTexture"); glTexImage2D = Bind("glTexImage2D"); diff --git a/OpenRA.Platforms.Default/Shader.cs b/OpenRA.Platforms.Default/Shader.cs index 61bc97fa33..43d3c9e592 100644 --- a/OpenRA.Platforms.Default/Shader.cs +++ b/OpenRA.Platforms.Default/Shader.cs @@ -24,6 +24,7 @@ namespace OpenRA.Platforms.Default readonly Dictionary samplers = new Dictionary(); readonly Dictionary textures = new Dictionary(); + readonly Queue unbindTextures = new Queue(); readonly uint program; protected uint CompileShaderObject(int type, string name) @@ -138,10 +139,21 @@ namespace OpenRA.Platforms.Default // bind the textures foreach (var kv in textures) { - OpenGL.glActiveTexture(OpenGL.GL_TEXTURE0 + kv.Key); - OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, ((ITextureInternal)kv.Value).ID); + var id = ((ITextureInternal)kv.Value).ID; + + // Evict disposed textures from the cache + if (OpenGL.glIsTexture(id)) + { + OpenGL.glActiveTexture(OpenGL.GL_TEXTURE0 + kv.Key); + OpenGL.glBindTexture(OpenGL.GL_TEXTURE_2D, id); + } + else + unbindTextures.Enqueue(kv.Key); } + while (unbindTextures.Count > 0) + textures.Remove(unbindTextures.Dequeue()); + OpenGL.CheckGLError(); }