Freeing Map Textures on Map Load

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Freeing Map Textures on Map Load

Post by Baker »

Yet another R00k gem ... essentially from aguirRe's Enhanced GLQuake but with a logical twist.

Freeing Map Textures On Map Load

Freeing map textures on map load clears the previously loaded map textures -- which in GLQuake are never freed. A benefit of this is never hitting the max texture limit. Additionally, on alternative platform engines with very limited memory (like the PSP, for instance) clearing world textures might be beneficial [since the PSP isn't using OpenGL, whatever the PSP equivalent of glDeleteTextures would need to be used].
Most Quake engines have a defined "texture upload limit" -- where a texture is uploaded via an OpenGL API to the video card. [in the engine check out GL_Upload8 and GL_Upload32 and the mechanics of GL_LoadTexture, etc.]

This texture upload limit might be 512 or 1024 textures or some such number. Loading several maps back to back causes a Quake "system error" where you get "TEXTURES > MAX_TEXTURES" or some such message.
Now deleting all the world textures on isn't instantaneous. And R00k says this about doubles map loading time.

The reason you only want to delete "world" textures (textures associated with maps and such) and not all textures is that you really don't want to have to reload all the 2D graphics like the HUD and the menu, of course.

Quicky and largely complete tutorial skeleton:

1. Create a cvar gl_free_world_textures somewhere and then register it (gl_draw.c or gl_rmisc.c would be one of the better places).

2. When loading a map, mark the textures with a TEX_WORLD flag to have a way to know which are world textures vs. textures for weapons or 2D graphics and such.

3. And when loading a map, check the cvar and call the following if gl_free_world_textures has a non-zero value.

Code: Select all

/*
================
GL_FreeTextures -- BPJ
================
*/
void GL_FreeTextures (void)
{
	int i, j;

	if (gl_free_world_textures.value == 0)
	{
		Con_DPrintf("GL_FreeTextures: Not Clearing old Map Textures.\n");
		return;
	}

	for (i = j = 0; i < numgltextures; ++i, ++j)
	{
		if (gltextures[i].texmode & TEX_WORLD)//Only clear out world textures... for now.
		{
			Con_DPrintf("GL_FreeTextures: Clearing texture %s\n", gltextures[i].identifier);
			glDeleteTextures(1, &gltextures[i].texnum);
			--j;
		}
		else if (j < i)
			gltextures[j] = gltextures[i];
	}

	numgltextures = j;
}
Setting this to on will allow an engine in theory to load an infinite number of maps instead of getting the "system error" about NUM_TEXTURES > GL_MAXTEXTURES after 10 to 20 maps.

And on a limited memory platform where memory is precious, adapting this to the platform 3D API should help preserve memory resources.
Downsider
Posts: 621
Joined: Tue Sep 16, 2008 1:35 am

Post by Downsider »

I'm assuming the tradeoff is increased load times?

EDIT: oh and this is cool ;D
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Post by mh »

A good compromise I use is to maintain a count on each texture. If the texture is used in the current map set the count to 0. Increment all texture counts by 1 on each map load. If a texture's count exceeds a predefined number (5 is pretty good for most cases) then it hasn't been used in a while so you can delete it.

This would give the advantage of keeping recently used textures live for a while in case they're needed again shortly, but textures which have not been used in the last few maps get deleted.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
mh
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Post by mh »

I forgot to mention that this ties in with an idea I've had, which was to build a comprehensive set of tutorials on "Fixing GLQuake" (I do believe that somebody mentioned once that there were a lot of things wrong with it... 8) )

The objective wouldn't be to get eye-candy, and nor would it be to produce an all-singing all-dancing bugfixed GLQuake at the end of it, but rather to provide a good solid reference that people coming new to the Quake source can use. They would be able to see all the work that needed to be done collected in one place, and would be able to implement the tutorials themselves and learn a lot about the engine (or at least one part of it) while doing so.

We'd end up with a really nice pool of collective knowledge and I don't see how it would be anything other than an "everyone wins" situation.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
Post Reply