ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/texcache.c
Revision: 1.4
Committed: Sun Aug 12 08:44:22 2007 UTC (16 years, 9 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

# Content
1 // all these must be powers of two
2 // width and height better be <=256 as we use bytes in the rendercache
3 #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 extern int tc_generation;
13
14 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 int tc_generation;
23
24 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 del_texture (first_texture->name);
50 g_slice_free (tc_texture, first_texture);
51 first_texture = next;
52 }
53
54 ++tc_generation;
55 }
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 match->name = gen_texture ();
84 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 }