--- deliantra/Deliantra-Client/texcache.c 2006/07/04 23:23:32 1.1 +++ deliantra/Deliantra-Client/texcache.c 2007/12/25 19:08:31 1.6 @@ -1,4 +1,5 @@ // all these must be powers of two +// width and height better be <=256 as we use bytes in the rendercache #define TC_WIDTH 256 #define TC_HEIGHT 256 #define TC_ROUND 4 @@ -8,18 +9,25 @@ int x, y, w, h; } tc_area; -void tc_get (tc_area *area, int width, int height); -void tc_put (tc_area *area); -void tc_clear (); +extern int tc_generation; + +static void tc_get (tc_area *area, int width, int height); +static void tc_put (tc_area *area); +static void tc_clear (void); +static void tc_backup (void); +static void tc_restore (void); ///////////////////////////////////////////////////////////////////////////// #include +int tc_generation; + typedef struct tc_texture { struct tc_texture *next; GLuint name; int avail; + char *saved; /* stores saved texture data */ } tc_texture; typedef struct tc_slice { @@ -31,7 +39,7 @@ static tc_texture *first_texture; void -tc_clear () +tc_clear (void) { int i; @@ -41,10 +49,46 @@ while (first_texture) { tc_texture *next = first_texture->next; - glDeleteTextures (1, &first_texture->name); + del_texture (first_texture->name); g_slice_free (tc_texture, first_texture); first_texture = next; } + + ++tc_generation; +} + +void +tc_backup (void) +{ + tc_texture *tex = first_texture; + while (tex) + { + tex->saved = g_slice_alloc (TC_WIDTH * TC_HEIGHT); + + glBindTexture (GL_TEXTURE_2D, tex->name); + glGetTexImage (GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved); + + tex = tex->next; + } +} + +void +tc_restore (void) +{ + tc_texture *tex = first_texture; + + while (tex) + { + glBindTexture (GL_TEXTURE_2D, tex->name); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved); + + g_slice_free1 (TC_WIDTH * TC_HEIGHT, tex->saved); + tex->saved = 0; + + tex = tex->next; + } } void @@ -71,10 +115,11 @@ if (!match) { match = g_slice_new (tc_texture); - match->next = first_texture; + match->next = first_texture; first_texture = match; - glGenTextures (1, &match->name); - match->avail = TC_HEIGHT; + match->name = gen_texture (); + match->avail = TC_HEIGHT; + match->saved = 0; glBindTexture (GL_TEXTURE_2D, match->name); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);