diff --git a/quakespasm/Quake/gl_texmgr.c b/quakespasm/Quake/gl_texmgr.c index 492c037b4..f92af8cb2 100644 --- a/quakespasm/Quake/gl_texmgr.c +++ b/quakespasm/Quake/gl_texmgr.c @@ -341,6 +341,8 @@ gltexture_t *TexMgr_NewTexture (void) return glt; } +static void GL_DeleteTexture (gltexture_t *texture); + /* ================ TexMgr_FreeTexture @@ -362,7 +364,7 @@ void TexMgr_FreeTexture (gltexture_t *kill) kill->next = free_gltextures; free_gltextures = kill; - glDeleteTextures(1, &kill->texnum); + GL_DeleteTexture(kill); numgltextures--; return; } @@ -375,7 +377,7 @@ void TexMgr_FreeTexture (gltexture_t *kill) kill->next = free_gltextures; free_gltextures = kill; - glDeleteTextures(1, &kill->texnum); + GL_DeleteTexture(kill); numgltextures--; return; } @@ -420,6 +422,21 @@ void TexMgr_FreeTexturesForOwner (qmodel_t *owner) } } +/* +================ +TexMgr_DeleteTextureObjects +================ +*/ +void TexMgr_DeleteTextureObjects (void) +{ + gltexture_t *glt; + + for (glt = active_gltextures; glt; glt = glt->next) + { + GL_DeleteTexture (glt); + } +} + /* ================================================================================ @@ -1466,3 +1483,23 @@ void GL_Bind (gltexture_t *texture) texture->visframe = r_framecount; } } + +/* +================ +GL_DeleteTexture -- ericw + +Wrapper around glDeleteTextures that also updates our cached current texture +binding, if necessary. +================ +*/ +static void GL_DeleteTexture (gltexture_t *texture) +{ + glDeleteTextures (1, &texture->texnum); + + if (texture->texnum == currenttexture[currenttarget - GL_TEXTURE0_ARB]) + { + currenttexture[currenttarget - GL_TEXTURE0_ARB] = 0; + } + + texture->texnum = 0; +} diff --git a/quakespasm/Quake/gl_texmgr.h b/quakespasm/Quake/gl_texmgr.h index 472d73428..f772df30b 100644 --- a/quakespasm/Quake/gl_texmgr.h +++ b/quakespasm/Quake/gl_texmgr.h @@ -85,6 +85,7 @@ void TexMgr_FreeTextures (unsigned int flags, unsigned int mask); void TexMgr_FreeTexturesForOwner (qmodel_t *owner); void TexMgr_NewGame (void); void TexMgr_Init (void); +void TexMgr_DeleteTextureObjects (void); // IMAGE LOADING gltexture_t *TexMgr_LoadImage (qmodel_t *owner, const char *name, int width, int height, enum srcformat format, diff --git a/quakespasm/Quake/gl_vidsdl.c b/quakespasm/Quake/gl_vidsdl.c index 37627cddd..c0c7ff4e4 100644 --- a/quakespasm/Quake/gl_vidsdl.c +++ b/quakespasm/Quake/gl_vidsdl.c @@ -676,6 +676,13 @@ static void VID_Restart (void) width, height, bpp, fullscreen? "fullscreen" : "windowed"); return; } + +// ericw -- depending on platform / SDL version, after a video mode change we +// can have a new context (all textures are already freed) or the same context +// as before, in which case we need to delete the old textures to avoid a +// memory leak. + + TexMgr_DeleteTextureObjects (); // // set new mode