ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/texcache.c
Revision: 1.6
Committed: Tue Dec 25 19:08:31 2007 UTC (16 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_03, rel-2_02, rel-0_9965, rel-0_9964, rel-0_9963, rel-2_05, rel-2_04, rel-0_9968, rel-2_0, rel-0_9972, rel-0_9973, rel-0_9974, rel-0_9975, rel-0_9976, rel-0_9977, rel-0_9978, rel-0_9971, rel-0_9967, rel-1_21, rel-0_9966
Changes since 1.5: +5 -3 lines
Log Message:
staticify

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.6 static void tc_get (tc_area *area, int width, int height);
15     static void tc_put (tc_area *area);
16     static void tc_clear (void);
17     static void tc_backup (void);
18     static void tc_restore (void);
19 root 1.1
20     /////////////////////////////////////////////////////////////////////////////
21    
22     #include <glib.h>
23    
24 root 1.2 int tc_generation;
25    
26 root 1.1 typedef struct tc_texture {
27     struct tc_texture *next;
28     GLuint name;
29     int avail;
30 root 1.5 char *saved; /* stores saved texture data */
31 root 1.1 } tc_texture;
32    
33     typedef struct tc_slice {
34     GLuint name;
35     int avail, y;
36     } tc_slice;
37    
38     static tc_slice slices[TC_HEIGHT / TC_ROUND];
39     static tc_texture *first_texture;
40    
41     void
42 root 1.5 tc_clear (void)
43 root 1.1 {
44     int i;
45    
46     for (i = TC_HEIGHT / TC_ROUND; i--; )
47     slices [i].name = 0;
48    
49     while (first_texture)
50     {
51     tc_texture *next = first_texture->next;
52 root 1.3 del_texture (first_texture->name);
53 root 1.1 g_slice_free (tc_texture, first_texture);
54     first_texture = next;
55     }
56 root 1.2
57     ++tc_generation;
58 root 1.1 }
59    
60     void
61 root 1.5 tc_backup (void)
62     {
63     tc_texture *tex = first_texture;
64     while (tex)
65     {
66     tex->saved = g_slice_alloc (TC_WIDTH * TC_HEIGHT);
67    
68     glBindTexture (GL_TEXTURE_2D, tex->name);
69     glGetTexImage (GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved);
70    
71     tex = tex->next;
72     }
73     }
74    
75     void
76     tc_restore (void)
77     {
78     tc_texture *tex = first_texture;
79    
80     while (tex)
81     {
82     glBindTexture (GL_TEXTURE_2D, tex->name);
83     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
84     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
85     glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, tex->saved);
86    
87     g_slice_free1 (TC_WIDTH * TC_HEIGHT, tex->saved);
88     tex->saved = 0;
89    
90     tex = tex->next;
91     }
92     }
93    
94     void
95 root 1.1 tc_get (tc_area *area, int width, int height)
96     {
97     int slice_height = MIN (height + TC_ROUND - 1, TC_HEIGHT) & ~(TC_ROUND - 1);
98     tc_slice *slice = slices + slice_height / TC_ROUND;
99    
100     area->w = width;
101     area->h = height;
102    
103     width = MIN (width, TC_WIDTH);
104    
105     if (!slice->name || slice->avail < width)
106     {
107     // try to find a texture with enough space
108     tc_texture *tex, *match = 0;
109    
110     for (tex = first_texture; tex; tex = tex->next)
111     if (tex->avail >= slice_height && (!match || match->avail > tex->avail))
112     match = tex;
113    
114     // create a new texture if necessary
115     if (!match)
116     {
117     match = g_slice_new (tc_texture);
118 root 1.5 match->next = first_texture;
119 root 1.1 first_texture = match;
120 root 1.5 match->name = gen_texture ();
121     match->avail = TC_HEIGHT;
122     match->saved = 0;
123 root 1.1
124     glBindTexture (GL_TEXTURE_2D, match->name);
125     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
126     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
127     glTexImage2D (GL_TEXTURE_2D, 0, GL_ALPHA, TC_WIDTH, TC_HEIGHT, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 0);
128     }
129    
130     match->avail -= slice_height;
131    
132     slice->name = match->name;
133     slice->avail = TC_WIDTH;
134     slice->y = match->avail;
135     }
136    
137     slice->avail -= width;
138    
139     area->name = slice->name;
140     area->x = slice->avail;
141     area->y = slice->y;
142     }
143    
144     void
145     tc_put (tc_area *area)
146     {
147     // our management is too primitive to support this operation yet
148     }