diff --git a/include/QF/model.h b/include/QF/model.h index d68d75ad7..4856b486e 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -422,6 +422,7 @@ typedef struct model_s { // additional model data cache_user_t cache; + void (*clear) (struct model_s *m); } model_t; // ============================================================================ diff --git a/libs/models/alias/glsl_model_alias.c b/libs/models/alias/glsl_model_alias.c index 68f90f59d..790290cdc 100644 --- a/libs/models/alias/glsl_model_alias.c +++ b/libs/models/alias/glsl_model_alias.c @@ -58,6 +58,42 @@ static vec3_t vertex_normals[NUMVERTEXNORMALS] = { #include "anorms.h" }; +static void +glsl_alias_clear (model_t *m) +{ + int i, j; + aliashdr_t *hdr; + GLuint bufs[2]; + maliasskindesc_t *skins; + maliasskingroup_t *group; + + m->needload = true; + + if (!(hdr = m->aliashdr)) + hdr = Cache_Get (&m->cache); + + bufs[0] = hdr->posedata; + bufs[1] = hdr->commands; + qfglDeleteBuffers (2, bufs); + + skins = ((maliasskindesc_t *) ((byte *) hdr + hdr->skindesc)); + for (i = 0; i < hdr->mdl.numskins; i++) { + if (skins[i].type == ALIAS_SKIN_GROUP) { + group = (maliasskingroup_t *) ((byte *) hdr + skins[i].skin); + for (j = 0; j < group->numskins; j++) { + GL_ReleaseTexture (group->skindescs[j].texnum); + } + } else { + GL_ReleaseTexture (skins[i].texnum); + } + } + + if (!m->aliashdr) { + Cache_Release (&m->cache); + Cache_Free (&m->cache); + } +} + void * Mod_LoadSkin (byte *skin, int skinsize, int snum, int gnum, qboolean group, maliasskindesc_t *skindesc) @@ -85,6 +121,7 @@ Mod_FinalizeAliasModel (model_t *m, aliashdr_t *hdr) { if (hdr->mdl.ident == HEADER_MDL16) VectorScale (hdr->mdl.scale, 1/256.0, hdr->mdl.scale); + m->clear = glsl_alias_clear; } void diff --git a/libs/models/brush/glsl_model_brush.c b/libs/models/brush/glsl_model_brush.c index b97b75b64..c362765cb 100644 --- a/libs/models/brush/glsl_model_brush.c +++ b/libs/models/brush/glsl_model_brush.c @@ -58,6 +58,26 @@ static __attribute__ ((used)) const char rcsid[] = "$Id$"; #include "compat.h" +static void +glsl_brush_clear (model_t *m) +{ + int i; + + m->needload = true; + for (i = 0; i < m->numtextures; i++) { + if (m->textures[i]->gl_texturenum) { + GL_ReleaseTexture (m->textures[i]->gl_texturenum); + m->textures[i]->gl_texturenum = 0; + } + } + for (i = 0; i < m->numsurfaces; i++) { + if (m->surfaces[i].polys) { + free (m->surfaces[i].polys); + m->surfaces[i].polys = 0; + } + } +} + void Mod_ProcessTexture (texture_t *tx) { @@ -95,6 +115,8 @@ Mod_LoadExternalTextures (model_t *mod) void Mod_LoadLighting (bsp_t *bsp) { + // a big hacky, but it's as good a place as any + loadmodel->clear = glsl_brush_clear; mod_lightmap_bytes = 1; if (!bsp->lightdatasize) { loadmodel->lightdata = NULL; diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index c90773cfd..85071dbb3 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -912,6 +912,8 @@ Mod_LoadBrushModel (model_t *mod, void *buffer) Mod_LoadEntities (bsp); Mod_LoadSubmodels (bsp); + BSP_Free(bsp); + Mod_MakeHull0 (); mod->numframes = 2; // regular and alternate animation diff --git a/libs/models/model.c b/libs/models/model.c index a7d852145..bda3c5046 100644 --- a/libs/models/model.c +++ b/libs/models/model.c @@ -120,10 +120,14 @@ Mod_ClearAll (void) model_t **mod; for (i = 0, mod = mod_known; i < mod_numknown; i++, mod++) { - if ((*mod)->type != mod_alias) - (*mod)->needload = true; - if ((*mod)->type == mod_sprite) - (*mod)->cache.data = 0; + if (!(*mod)->needload && (*mod)->clear) { + (*mod)->clear (*mod); + } else { + if ((*mod)->type != mod_alias) + (*mod)->needload = true; + if ((*mod)->type == mod_sprite) + (*mod)->cache.data = 0; + } } } @@ -237,7 +241,7 @@ static model_t * Mod_LoadModel (model_t *mod, qboolean crash) { if (!mod->needload) { - if (mod->type == mod_alias) { + if (mod->type == mod_alias && !mod->aliashdr) { if (Cache_Check (&mod->cache)) return mod; } else diff --git a/libs/models/sprite/glsl_model_sprite.c b/libs/models/sprite/glsl_model_sprite.c index aaa7d8e1f..cfb7d4229 100644 --- a/libs/models/sprite/glsl_model_sprite.c +++ b/libs/models/sprite/glsl_model_sprite.c @@ -31,8 +31,7 @@ # include "config.h" #endif -static __attribute__ ((used)) const char rcsid[] = - "$Id$"; +static __attribute__ ((used)) const char rcsid[] = "$Id$"; #ifdef HAVE_STRING_H # include @@ -49,11 +48,36 @@ static __attribute__ ((used)) const char rcsid[] = #include "compat.h" +static void +glsl_sprite_clear (model_t *m) +{ + int i, j; + msprite_t *sprite = (msprite_t *) m->cache.data; + mspritegroup_t *group; + mspriteframe_t *frame; + + m->needload = true; + m->cache.data = 0; + for (i = 0; i < sprite->numframes; i++) { + if (sprite->frames[i].type == SPR_SINGLE) { + frame = sprite->frames[i].frameptr; + GL_ReleaseTexture (frame->gl_texturenum); + } else { + group = (mspritegroup_t *) sprite->frames[i].frameptr; + for (j = 0; j < group->numframes; j++) { + frame = group->frames[j]; + GL_ReleaseTexture (frame->gl_texturenum); + } + } + } +} + void Mod_SpriteLoadTexture (mspriteframe_t *pspriteframe, int framenum) { const char *name; + loadmodel->clear = glsl_sprite_clear; name = va ("%s_%i", loadmodel->name, framenum); pspriteframe->gl_texturenum = GL_LoadQuakeTexture (name, pspriteframe->width, pspriteframe->height, diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index bf8d1427a..16814de43 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -466,7 +466,6 @@ build_surf_displist (model_t **models, msurface_t *fa, int base, numtris = numverts - 2; numindices = numtris * 3; verts = alloca (numverts * sizeof (bspvert_t)); - //FIXME leak poly = malloc (field_offset (glslpoly_t, indices[numindices])); poly->count = numindices; for (i = 0, ind = poly->indices; i < numtris; i++) { diff --git a/libs/video/targets/vid_common_glsl.c b/libs/video/targets/vid_common_glsl.c index 1a77b3f94..21e14d0e2 100644 --- a/libs/video/targets/vid_common_glsl.c +++ b/libs/video/targets/vid_common_glsl.c @@ -313,6 +313,7 @@ dump_program (const char *name, int program) Sys_Printf ("Attribute %i name \"%s\" size %i type %s\n", (int)ind, pname->str, (int)psize, type_name (ptype)); } + dstring_delete (pname); } int