ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/texcache.c
Revision: 1.1
Committed: Tue Jul 4 23:23:32 2006 UTC (17 years, 10 months ago) by root
Content type: text/plain
Branch: MAIN
Log Message:
Get rid of cairo completely (yay!) and of ft2 factually (still need the
library as it included pangofc), by introducing a custom pango opengl
renderer.

Text rendering now no longer requires the distinction between rgba and
grayscale modes, requires much less texture space and memory, and is
faster on accelerated hardware (and possibly with software rendering, too).

All at the cost of only 1200 lines or so.

File Contents

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