ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cf.schmorp.de/Deliantra-Client/texcache.c
Revision: 1.4
Committed: Sun Aug 12 08:44:22 2007 UTC (16 years, 11 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-0_99, rel-0_9958, rel-0_9960, rel-0_9956, rel-0_9957, rel-0_9955, rel-0_9959, rel-0_995
Changes since 1.3: +1 -0 lines
Log Message:
use an compressed format for glyph quad vectors. this reduces
the size of e.g. the opengl info from 200k to 20k, and typical
sizes for labels are now <<100 bytes. the cost is full immediate
mode submission of coordinates (cpu), but glInterleavedArrays is
likely not much faster and modern cpus probably prefer more decoding
over more cache misses.

File Contents

# User Rev Content
1 root 1.1 // all these must be powers of two
2 root 1.4 // width and height better be <=256 as we use bytes in the rendercache
3 root 1.1 #define TC_WIDTH 256
4     #define TC_HEIGHT 256
5     #define TC_ROUND 4
6    
7     typedef struct {
8     GLuint name;
9     int x, y, w, h;
10     } tc_area;
11    
12 root 1.2 extern int tc_generation;
13    
14 root 1.1 void tc_get (tc_area *area, int width, int height);
15     void tc_put (tc_area *area);
16     void tc_clear ();
17    
18     /////////////////////////////////////////////////////////////////////////////
19    
20     #include <glib.h>
21    
22 root 1.2 int tc_generation;
23    
24 root 1.1 typedef struct tc_texture {
25     struct tc_texture *next;
26     GLuint name;
27     int avail;
28     } tc_texture;
29    
30     typedef struct tc_slice {
31     GLuint name;
32     int avail, y;
33     } tc_slice;
34    
35     static tc_slice slices[TC_HEIGHT / TC_ROUND];
36     static tc_texture *first_texture;
37    
38     void
39     tc_clear ()
40     {
41     int i;
42    
43     for (i = TC_HEIGHT / TC_ROUND; i--; )
44     slices [i].name = 0;
45    
46     while (first_texture)
47     {
48     tc_texture *next = first_texture->next;
49 root 1.3 del_texture (first_texture->name);
50 root 1.1 g_slice_free (tc_texture, first_texture);
51     first_texture = next;
52     }
53 root 1.2
54     ++tc_generation;
55 root 1.1 }
56    
57     void
58     tc_get (tc_area *area, int width, int height)
59     {
60     int slice_height = MIN (height + TC_ROUND - 1, TC_HEIGHT) & ~(TC_ROUND - 1);
61     tc_slice *slice = slices + slice_height / TC_ROUND;
62    
63     area->w = width;
64     area->h = height;
65    
66     width = MIN (width, TC_WIDTH);
67    
68     if (!slice->name || slice->avail < width)
69     {
70     // try to find a texture with enough space
71     tc_texture *tex, *match = 0;
72    
73     for (tex = first_texture; tex; tex = tex->next)
74     if (tex->avail >= slice_height && (!match || match->avail > tex->avail))
75     match = tex;
76    
77     // create a new texture if necessary
78     if (!match)
79     {
80     match = g_slice_new (tc_texture);
81     match->next = first_texture;
82     first_texture = match;
83 root 1.3 match->name = gen_texture ();
84 root 1.1 match->avail = TC_HEIGHT;
85    
86     glBindTexture (GL_TEXTURE_2D, match->name);
87     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
88     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
89     glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
90     }
91    
92     match->avail -= slice_height;
93    
94     slice->name = match->name;
95     slice->avail = TC_WIDTH;
96     slice->y = match->avail;
97     }
98    
99     slice->avail -= width;
100    
101     area->name = slice->name;
102     area->x = slice->avail;
103     area->y = slice->y;
104     }
105    
106     void
107     tc_put (tc_area *area)
108     {
109     // our management is too primitive to support this operation yet
110     }